package com.yenlien.traceyun.plant.service;

import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.hutool.core.lang.Assert;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableBiMap;
import com.yenlien.traceyun.business.bean.RestURL;
import com.yenlien.traceyun.business.controller.response.BaseSoilView;
import com.yenlien.traceyun.business.dao.BaseSoilDao;
import com.yenlien.traceyun.business.dao.EquipmentDao;
import com.yenlien.traceyun.business.entity.BaseSoil;
import com.yenlien.traceyun.business.entity.Equipment;
import com.yenlien.traceyun.business.interceptor.UserAuthUtil;
import com.yenlien.traceyun.business.service.BaseSoilService;
import com.yenlien.traceyun.business.service.EquipmentService;
import com.yenlien.traceyun.business.service.rest.RestService;
import com.yenlien.traceyun.business.utils.EasyPoiUtils;
import com.yenlien.traceyun.common.utils.Tools;
import com.yenlien.traceyun.plant.bean.excel.*;
import com.yenlien.traceyun.plant.dao.*;
import com.yenlien.traceyun.plant.dock_device.DevState;
import com.yenlien.traceyun.plant.dock_device.kebai.KeBaiData;
import com.yenlien.traceyun.plant.dock_device.xinfengxiang.XinFengXiang;
import com.yenlien.traceyun.plant.entity.*;
import com.yenlien.traceyun.plant.utils.MathUtils;
import com.yenlien.traceyun.webase.exception.BusinessException;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;

import static com.yenlien.traceyun.common.utils.Tools.DATE_TIME_FORMAT;
import static com.yenlien.traceyun.plant.dock_device.DevState.*;
import static com.yenlien.traceyun.plant.utils.Tools.DATE_FORMATTER;
import static com.yenlien.traceyun.plant.utils.Tools.DATE_TIME_FORMATTER;

/**
 * @Date 2023/8/17
 * @Author jiaLong
 * @Descript
 */
@Service
public class IotService {

    @Autowired
    private EquipmentDao equipmentDao;
    @Autowired
    private ShiJiRuiTongDao shiJiRuiTongDao;
    @Autowired
    private XinFengXiangDao xinFengXiangDao;
    @Autowired
    private KeBaiDao keBaiDao;
    @Autowired
    private DevAlarmDao devAlarmDao;
    @Autowired
    private DevThresholdDao devThresholdDao;
    @Autowired
    private BaseSoilService baseSoilService;
    @Autowired
    private PlantDao plantDao;
    @Autowired
    private FarmDao farmDao;
    @Autowired
    private EquipmentService equipmentService;
    @Autowired
    private CompanyDao companyDao;
    @Autowired
    private AlarmDao alarmDao;
    @Autowired
    private BaseSoilDao baseSoilDao;
    @Autowired
    private ReapDao reapDao;
    @Autowired
    private ReapDetailDao reapDetailDao;
    @Autowired
    private SDRKDataDao sdrkDataDao;
    @Autowired
    private OKQDataDao okqDataDao;
    @Autowired
    private OKQEnvDataDao okqEnvDataDao;
    @Autowired
    private ArticleDao articleDao;
    @Autowired
    private RestService restService;
    @Autowired
    private FruitDataDao fruitDataDao;


    public Object getPlotByCompId(String companyId) {
        if(StringUtils.isBlank(companyId)){
            companyId = UserAuthUtil.getLoginUser().getCompanyId();
        }
        return baseSoilDao.getByCompId(companyId);
    }
    public JSONObject getPlantData(String companyId, String plotId) {
        // 种植和地块数据
        if(StringUtils.isBlank(companyId)){
            companyId = UserAuthUtil.getLoginUser().getCompanyId();
        }
        List<JSONObject> baseSoilList = baseSoilDao.getByPlotId(plotId);
        JSONObject result = genPlantResult();
        if(CollectionUtils.isEmpty(baseSoilList)){
            return result;
        }
        Double areaCnt = baseSoilList.stream().map(x -> x.getDouble("area")).reduce(0D, Double::sum);
        result.put("areaCnt", MathUtils.df.format(areaCnt));
        result.put("soilNum", baseSoilList.size());

        List<Plant> plantList = plantDao.findByCompanyIdAndSoilId(companyId, plotId);
        if(CollectionUtils.isEmpty(plantList)){
            return result;
        }
        Double areaPlantCnt = plantList.stream().map(Plant::getPlantArea).map(Double::valueOf).reduce(0D, Double::sum);
        result.put("areaPlantCnt", MathUtils.df.format(areaPlantCnt));
        result.put("areaNotPlantCnt", MathUtils.df.format(areaCnt - areaPlantCnt));
//        result.put("plantNum", plantList.stream().collect(Collectors.groupingBy(Plant::getPlantName)).size());
        result.put("plantNum", plantList.size());

        List<JSONObject> list = new ArrayList<>();
        for(JSONObject baseSoil : baseSoilList){
            JSONObject json = new JSONObject();
            List<Map<String, Object>> maps = new ArrayList<>();
            List<Plant> plantSoilList = plantList.stream().filter(x -> x.getSoilId().equals(baseSoil.getString("id"))).collect(Collectors.toList());
            for (Plant plant : plantSoilList) {
                Map<String, Object> map = new HashMap<>();
                map.put("plantArea", plant.getPlantArea());            // 种植面积
                map.put("jyName", plant.getJyName());
                map.put("plantName", plant.getPlantName());
                map.put("soilRatio", MathUtils.percentage(Double.valueOf(plant.getPlantArea()), baseSoil.getDouble("area")));    // 地块占比
                map.put("allRatio", MathUtils.percentage(Double.valueOf(plant.getPlantArea()), areaCnt));     // 总占比
                maps.add(map);
            }
            json.put("plantList", maps);
            json.put("baseSoil", baseSoil.getString("name"));
            list.add(json);
        }
        result.put("plantData", list);
        return result;
    }
    public List<Plant> getPlantBySoilId(String soilId, String plantName) {
        List<Plant> plantList;
//        BaseSoil baseSoil = baseSoilDao.findById(soilId).orElseThrow(() -> new BusinessException("该地块不存在"));
        if(StringUtils.isBlank(plantName)){
            plantList = plantDao.findBySoilId(soilId);
        }else {
            plantList = plantDao.getPlantBySoilId(soilId, plantName);
        }
        LocalDate now = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        for(Plant plant : plantList){
//            List<Farm> farmList = farmDao.findByPlantId(plant.getId()).stream().sorted(Comparator.comparing(Farm::getBeginTime)).collect(Collectors.toList());
            List<Farm> farmList = farmDao.findByPlantId(plant.getId()).stream()
                    .sorted(Comparator.comparing(x -> Integer.valueOf(x.getBeginTime().replaceAll("-", "")))).collect(Collectors.toList());
            plant.setFarmList(farmList);
            if(1 == plant.getReapStatus() || 2 == plant.getReapStatus()){
                List<Reap> reapList = reapDao.findByPlantBatch(plant.getBatch());
                for(Reap reap : reapList){
                    LocalDate beginTime = LocalDate.parse(reap.getBeginTime(), formatter);
                    LocalDate endTime = LocalDate.parse(reap.getEndTime(), formatter);
                    int days = Period.between(beginTime, endTime).getDays();
                    if(days < 0)
                        days = 0;
                    reap.setReapDays(days + 1);
                    JSONObject reapName = reapDetailDao.getReapNameByReapId(reap.getId());
                    reap.setReapName(reapName.getString("reap_name"));
                    reap.setReapPart(reapName.getString("reap_part"));
                }
                plant.setReapList(reapList);
            }else {
                LocalDate plantTime = LocalDate.parse(plant.getPlantTime(), Tools.DATE_TIME_BIAS_FORMATTER);
                Period next = Period.between(plantTime, now);
                plant.setGrowDays(next.getDays());
            }
        }
//        JSONObject object = new JSONObject();
//        object.put("baseSoil", baseSoil);
//        object.put("plantList", plantList);
        return plantList;
    }

    public Integer getOnlineNum(List<Equipment> equipmentList){
        Integer onlineNum = 0;
        for(Equipment equipment : equipmentList){
            if("1".equals(equipment.getStatus()))
                onlineNum += 1;
        }
        return onlineNum;
    }

    public Object getVideoUrl(String devId, String companyId){
        if (StringUtils.isBlank(companyId))
            companyId = UserAuthUtil.getLoginUser().getCompanyId();
        Equipment equipment = equipmentDao.findBySerialAndCompanyId(devId, companyId);
        if(equipment == null)
            throw new BusinessException("该设备不存在");
        return DevState.getVideo(devId, tokenMap.get(equipment.getAppKey() + companyId));
    }

    public Object videoMove(String devId, String val, String companyId) {
        if (StringUtils.isBlank(companyId))
            companyId = UserAuthUtil.getLoginUser().getCompanyId();
        Equipment equipment = equipmentDao.findBySerialAndCompanyId(devId, companyId);
        if(equipment == null)
            throw new BusinessException("该设备不存在");
        return DevState.videoMove(devId, val, tokenMap.get(equipment.getAppKey() + companyId));
    }

    public JSONObject getAppDevData(String companyId) {
        if (StringUtils.isBlank(companyId))
            companyId = UserAuthUtil.getLoginUser().getCompanyId();
        JSONObject object = new JSONObject();
        List<Equipment> equipmentList = DevState.devMap.get(companyId);
        if(CollectionUtils.isNotEmpty(equipmentList)){
            return object;
        }
        List<Equipment> videoEquList = DevState.videoDevMap.get(companyId);
        if(CollectionUtils.isNotEmpty(videoEquList))
            equipmentList.addAll(videoEquList);
        Integer onlineNum = getOnlineNum(equipmentList);
        Integer offlineNum = equipmentList.size()  - onlineNum;
        Map<String, List<Equipment>> listMap = equipmentList.stream().collect(Collectors.groupingBy(Equipment::getType));
        List<JSONObject> jsonList = new ArrayList<>();
        for(String key : listMap.keySet()){
            JSONObject json = new JSONObject();
            json.put("name", key);
            List<Equipment> list = listMap.get(key);
            int size = list.size();
            json.put("total", size);
            long online = list.stream().filter(x -> "1".equals(x.getStatus())).count();
            json.put("online", online);
            json.put("offline", size - online);
            jsonList.add(json);
        }
        Integer total;
        total = onlineNum + offlineNum;
        object.put("onlineNum", onlineNum);         // 在线数量
        object.put("onlineNumRatio", MathUtils.percentage(onlineNum, total));    // 在线百分比
        object.put("offlineNum", offlineNum);       // 离线数量
        object.put("offlineNumRatio", MathUtils.percentage(offlineNum, total));  // 离线百分比
        object.put("devState", jsonList);           // 每种类型的设备总量和在线数量
        object.put("allDev", equipmentList);
        return object;
    }



    public JSONObject getDevData(String companyId) {
        JSONObject object = new JSONObject();
        if(StringUtils.isBlank(companyId)){
            companyId = UserAuthUtil.getLoginUser().getCompanyId();
        }
        Company company = companyDao.findById(companyId);
        List<Equipment> equipmentList;
        List<Equipment> devList = devMap.get(companyId);
        if(CollectionUtils.isEmpty(devList)){
            equipmentList = equipmentService.findByCompanyId(companyId);
            object.put("vrList", equipmentList.stream().filter(x -> "VR".equals(x.getType())).collect(Collectors.toList()));
        }else{
            // 直接 get 内存地址一样， devList添加值以后 devMap 中该key对应的元素也会增加值
            devList = devList.stream().collect(Collectors.toList());
            List<Equipment> videoList = videoDevMap.get(companyId);
            if(CollectionUtils.isNotEmpty(videoList))
                devList.addAll(videoList.stream().collect(Collectors.toList()));
            equipmentList = devList;
            object.put("vrList", equipmentService.findByTypeAndCompanyId("VR", companyId));
        }

        // 种植数据
        List<Map<String, Object>> maps = new ArrayList<>();
        List<Plant> plantList = plantDao.findByCompanyId(companyId);
        JSONObject json = new JSONObject();
        JSONObject json2 = new JSONObject();
        if(CollectionUtils.isNotEmpty(plantList)){
            Double plantAreaCnt = plantList.stream().map(Plant::getPlantArea).map(Double::valueOf).reduce(0D, Double::sum);
            Map<String, List<Plant>> listMap = plantList.stream().collect(Collectors.groupingBy(Plant::getPlantName));
            for (String key : listMap.keySet()) {
                Double plantArea = listMap.get(key).stream().map(Plant::getPlantArea).map(Double::valueOf).reduce(0D, Double::sum);
                Map<String, Object> map = new HashMap<>();
                map.put("area", plantArea);
                map.put("jyName", key);
                map.put("ratio", MathUtils.percentage(plantArea, plantAreaCnt));
                maps.add(map);
            }
            json.put("plantAreaCnt", plantAreaCnt);
            json.put("plantList", maps);

            // 种植数据pro
//            for(Plant plant : plantList){
//                plant.setFarmList(farmDao.findByPlantId(plantList.get(0).getId()).stream()
//                        .sorted(Comparator.comparing(x -> Integer.valueOf(x.getBeginTime().replaceAll("-", "").substring(0, 8)))).collect(Collectors.toList()));
//                plant.setBaseSoil(baseSoilDao.getById(plant.getSoilId()));
//            }
            List<Farm> farmList = new ArrayList<>();
//            for(Plant plant : plantList){
//                farmList = farmDao.getByBatch(plant.getBatch());
//                if(CollectionUtils.isNotEmpty(farmList)){
//                    farmList = farmList.stream()
//                            .sorted(Comparator.comparing(x -> Integer.valueOf(x.getBeginTime().replaceAll("-", "").substring(0, 8)))).collect(Collectors.toList());
//                    break;
//                }
//            }
            json2.put("farmList", farmList);

            // 淳化县大屏农事
            LocalDate now = LocalDate.now();
//            List<Farm> farmTimeList = farmDao.getByTime(now.minusDays(4).format(DATE_FORMATTER), now.plusDays(3).format(DATE_FORMATTER));
            List<Farm> farmTimeList = farmDao.getByTime(now.format(DATE_FORMATTER), now.plusDays(8).format(DATE_FORMATTER));
            json2.put("farmData", getFarmData(farmTimeList));

            json2.put("plant", plantList.get(0));
            json2.put("plantList", plantList);
        }

        List<BaseSoilView> baseSoilViews = baseSoilService.findinitAll2(StringUtils.isBlank(companyId) ? UserAuthUtil.getLoginUser().getCompanyId() :  companyId);
        for(BaseSoilView baseSoilView : baseSoilViews){
            if(2 == baseSoilView.getType()){
                List<Plant> soilPlantList = plantDao.findBySoilId(baseSoilView.getId());
                for(Plant plant : soilPlantList){
                    plant.setFarmList(farmDao.getByBatch(plant.getBatch()));
                }
                baseSoilView.setPlantList(soilPlantList);
            }
        }

        object.put("plantData", json);
        object.put("newPlantData", json2);             // 果园二期种植数据
        object.put("company", companyDao.findById(companyId));                  // 当前企业信息
        object.put("baseSoilList", baseSoilViews.stream().filter(x -> 1 != x.getType()).collect(Collectors.toList()));                  // 地块

        if (CollectionUtils.isEmpty(equipmentList)) {
            List<Object> list = new ArrayList<>();
            object.put("envData", list);                // 气象数据
            object.put("envList", list);                // 气象设备列表
            object.put("insect", list);                 // 果园一期虫情图表
            object.put("insectManufacturer", "");       // 根据虫情设备厂商页面适配
            object.put("insectData", list);             // 果园一期虫情数据
            object.put("insectList", 0);                // 虫情设备列表
            object.put("videoData", 0);                 // 视频播放地址
            object.put("videoList", list);              // 视频设备列表
            object.put("soilData", list);               // 土壤数据
            object.put("soilList", list);               // 土壤设备列表
            object.put("waterData", list);              // 水质数据
            object.put("waterList", list);              // 水质设备列表
            object.put("alarmList", list);              // 果园一期报警数据
            object.put("plantData", "");                // 果园一期种植数据
            object.put("killInsectData", "");           // 杀虫灯数据
            object.put("killInsectDevList", "");        // 杀虫灯设备列表
            object.put("solenoidValveDevList", list);        // 电磁阀设备列表
            object.put("birdRepellentDevList", list);        // 驱鸟器设备列表
            return object;
        }
        List<Equipment> soilDevlist = equipmentList.stream().filter(x -> EQU_TYPE_SOIL.equals(x.getType())).collect(Collectors.toList());
        List<Equipment> waterDevlist = equipmentList.stream().filter(x -> EQU_TYPE_WATER.equals(x.getType())).collect(Collectors.toList());
        List<Equipment> envDevList = equipmentList.stream().filter(x -> EQU_TYPE_ENV.equals(x.getType())).collect(Collectors.toList());
        List<Equipment> insectDevlist = equipmentList.stream().filter(x -> EQU_TYPE_INSECT.equals(x.getType())).collect(Collectors.toList());
        List<Equipment> killInsectDevList = equipmentList.stream().filter(x -> EQU_TYPE_KILL_INSECT.equals(x.getType())).collect(Collectors.toList());

//        List<Equipment> solenoidValveDevList = equipmentList.stream().filter(x -> EQU_TYPE_SOLENOID_VALVE.equals(x.getType())).collect(Collectors.toList());
//        List<Equipment> birdRepellentDevList = equipmentList.stream().filter(x -> EQU_TYPE_BIRD_REPELLENT.equals(x.getType())).collect(Collectors.toList());
        object.put("solenoidValveDevList", equipmentDao.findByType(EQU_TYPE_SOLENOID_VALVE));
        object.put("birdRepellentDevList", equipmentDao.findByType(EQU_TYPE_BIRD_REPELLENT));

        List<Equipment> videoDevList = equipmentList.stream().filter(x -> EQU_TYPE_VIDEO.equals(x.getType())).collect(Collectors.toList());

        // 气象
        List<ShiJiRuiTong> envDataList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(envDevList)) {
            Equipment equipment = envDevList.get(0);
            if (EQU_MANUFACTURER_XFX.equals(equipment.getManufacturer())) {
                List<ShiJiRuiTong> data = (List<ShiJiRuiTong>) dataMap.get(equipment.getId());
                envDataList.addAll(data == null ? group(JSONArray.parseArray(JSONObject.toJSONString(xinFengXiangDao.getLast(equipment.getId(), 25)), ShiJiRuiTong.class)) : data);
            } else if (EQU_MANUFACTURER_KB.equals(equipment.getManufacturer())) {
                List<ShiJiRuiTong> data = (List<ShiJiRuiTong>) dataMap.get(equipment.getId());
                envDataList.addAll(data == null ? group(JSONArray.parseArray(JSONObject.toJSONString(keBaiDao.getLast(equipment.getId(), 25)), ShiJiRuiTong.class)) : data);
            } else if (EQU_MANUFACTURER_SJRT.equals(equipment.getManufacturer())) {
                List<ShiJiRuiTong> data = (List<ShiJiRuiTong>) dataMap.get(equipment.getId());
                envDataList.addAll(data == null ? group(shiJiRuiTongDao.getLast(equipment.getId(), 20)) : data);
            } else if (EQU_MANUFACTURER_OKQ.equals(equipment.getManufacturer())) {
                List<ShiJiRuiTong> data = (List<ShiJiRuiTong>) dataMap.get(equipment.getId());
                envDataList.addAll(data == null ? group(JSONArray.parseArray(JSONObject.toJSONString(okqEnvDataDao.getLast(equipment.getId(), 25)), ShiJiRuiTong.class)) : data);
            }
        }
        object.put("envData", envDataList);
        object.put("envList", envDevList);
        if (CollectionUtils.isNotEmpty(insectDevlist)) {
            Equipment equipment = insectDevlist.get(0);
            if(EQU_MANUFACTURER_SJRT.equals(equipment.getManufacturer())){
                List<ShiJiRuiTong> cwInsect = shiJiRuiTongDao.getCWInsect(companyId);
                Map<String, List<ShiJiRuiTong>> listMap = cwInsect.stream().collect(Collectors.groupingBy(x -> x.getCtime().substring(0, 10)));
                List<JSONObject> list = new ArrayList<>();
                for (String key : listMap.keySet()) {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("date", key);
                    jsonObject.put("value", listMap.get(key).size());
                    list.add(jsonObject);
                }
                object.put("insect", list);                 // 虫情图表
                object.put("insectData", cwInsect);         // 虫情数据
            }else if(EQU_MANUFACTURER_OKQ.equals(equipment.getManufacturer())){
                object.put("insect", getOKQInsectData(equipment));
                object.put("insectData", getOKQInsectAnalyse(equipment));
            }
            object.put("insectManufacturer", equipment.getManufacturer());
        } else {
            object.put("insect", "");
            object.put("insectData", "");
        }

        object.put("insectList", insectDevlist);

        if (CollectionUtils.isNotEmpty(killInsectDevList)) {
            object.put("killInsectData", shiJiRuiTongDao.getLast(killInsectDevList.get(0).getId(), 10));         // 杀虫灯数据
        } else {
            object.put("killInsectData", "");
        }
        object.put("killInsectDevList", killInsectDevList);

        if (CollectionUtils.isNotEmpty(videoDevList)) {
            Equipment equipment = videoDevList.get(0);
            if (EQU_MANUFACTURER_SJRT.equals(equipment.getManufacturer())) {
                object.put("videoData", videoDevList.get(0).getRtspHd());
            } else {
                object.put("videoData", equipment.getRtspHd());
            }
        }
        object.put("videoList", videoDevList);


        if (CollectionUtils.isNotEmpty(soilDevlist)) {
            Equipment equipment = soilDevlist.get(0);
            if (EQU_MANUFACTURER_SJRT.equals(equipment.getManufacturer())) {
                object.put("soilData", group(shiJiRuiTongDao.getLast(soilDevlist.get(0).getId(), 20)));
            }  else if(EQU_MANUFACTURER_XFX.equals(equipment.getManufacturer())) {
                object.put("soilData", group(JSONArray.parseArray(JSONObject.toJSONString(xinFengXiangDao.getLast(soilDevlist.get(0).getId(), 20)), ShiJiRuiTong.class)));
            }
        }
        object.put("soilList", soilDevlist);

        if (CollectionUtils.isNotEmpty(waterDevlist)) {
            Equipment equipment = waterDevlist.get(0);
            if (EQU_MANUFACTURER_SJRT.equals(equipment.getManufacturer())) {
                object.put("waterData", group(shiJiRuiTongDao.getLast(waterDevlist.get(0).getId(), 15)));
                object.put("waterDataList", shiJiRuiTongDao.getWaterData(equipment.getId(), LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
            } else {
                object.put("waterData", "");
                object.put("waterDataList", "");
            }
        } else {
            object.put("waterData", "");
            object.put("waterDataList", "");
        }
        object.put("waterList", waterDevlist);
        object.put("company", company);
        object.put("alarmList", alarmDao.getHistoryDataNum(10, companyId));
        object.put("newAlarmList", devAlarmDao.getHistoryDataNum(10, companyId));
        return object;
    }

    public Map<String, Object> getFarmData(LocalDate time, String type){
        List<Farm> farms;
        LocalDate startTime ;
        LocalDate endTime;
        if("week".equals(type)){
            startTime = time.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
            endTime = time.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
        }else if("month".equals(type)){
            startTime = time.with(TemporalAdjusters.firstDayOfMonth());
            endTime = time.with(TemporalAdjusters.lastDayOfMonth());
        }else if("year".equals(type)){
            startTime = time.with(TemporalAdjusters.firstDayOfYear());
            endTime = time.with(TemporalAdjusters.lastDayOfYear());
        }else
            throw new BusinessException("type参数错误");
        farms = farmDao.getByTime(startTime.format(DATE_FORMATTER), endTime.format(DATE_FORMATTER));
        return getFarmData(farms);
    }


    public Map<String, Object> getFarmData(List<Farm> farmList){
        List<HashMap<String, String>> mapList = new ArrayList<>();
        List<String> typeList = farmList.stream().filter(x -> StringUtils.isNotBlank(x.getType())).map(farm -> {
            HashMap<String, String> map = new HashMap<>();
            map.put("category", farm.getType());
            map.put("series", farm.getType());
            map.put("taskType", farm.getTaskType());
            map.put("startTime", farm.getBeginTime());
            map.put("endTime", farm.getEndTime());
            mapList.add(map);
            return farm.getType();
        }).collect(Collectors.toList());
        Map<String, Object> farmData = new HashMap<>();
        farmData.put("data", mapList);
        farmData.put("typeList", typeList);
        return farmData;
    }


    public List<JSONObject> getOKQInsectData(Equipment equipment) {
        List<OKQData> insectLast = okqDataDao.getInsectLast(equipment.getId(), 15);
        List<JSONObject> dataList = new ArrayList<>();
        for (OKQData okqData : insectLast) {
            JSONObject insectData = new JSONObject();
            if (StringUtils.isBlank(okqData.getPictureAnalysis())) {
                insectData.put("pictureUrl", okqData.getPictureUrl());
                insectData.put("time", okqData.getCTime());
                insectData.put("insectTypeNumList", new ArrayList<>());
                insectData.put("exhibitionPath", "");
                dataList.add(insectData);
                continue;
            }
            JSONObject jsonObject = JSONObject.parseObject(okqData.getPictureAnalysis());
            Set<String> keySet = jsonObject.keySet();
            List<JSONObject> insectTypeNumList = new ArrayList<>();
            JSONObject insectTypeNum = new JSONObject();
            for (String key : keySet) {
                insectTypeNum.put("insectName", key);
                insectTypeNum.put("num", jsonObject.getJSONArray(key).size());
                insectTypeNum.put("time", okqData.getCTime());
                insectTypeNumList.add(insectTypeNum);
            }
            insectData.put("insectTypeNumList", insectTypeNumList);
            insectData.put("pictureUrl", okqData.getPictureUrl());
            insectData.put("exhibitionPath", okqData.getExhibitionPath());
            insectData.put("time", okqData.getCTime());
            dataList.add(insectData);
        }
        // 空属性排在后面
        Comparator<JSONObject> comparator = Comparator.comparing(x -> x.getString("insectTypeNumList"),
                Comparator.nullsLast(Comparator.naturalOrder()));
        dataList.sort(comparator);
        return dataList;
    }

    public HashMap<String, Object> getOKQInsectAnalyse(Equipment equipment){
        // 图表数据取七天到现在
        List<JSONObject> pictureAnalysisList = okqDataDao.getInsectLastSeven(equipment.getId()).stream().filter(x -> StringUtils.isNotBlank(x.getString("pictureAnalysis"))).collect(Collectors.toList());
        List<JSONObject> insectAnalyseList = new ArrayList<>();
        for(JSONObject json : pictureAnalysisList){
            String cTime = json.getString("cTime");
            JSONObject pictureAnalysis = json.getJSONObject("pictureAnalysis");
            Set<String> keySet = pictureAnalysis.keySet();
            JSONObject insectTypeNum = new JSONObject();
            for(String key : keySet){
                insectTypeNum.put("insectName", key);
                insectTypeNum.put("num", pictureAnalysis.getJSONArray(key).size());
                insectTypeNum.put("time", cTime);
                insectAnalyseList.add(insectTypeNum);
            }
        }
        Map<String, List<JSONObject>> insectNameMapList = insectAnalyseList.stream().collect(Collectors.groupingBy(x -> x.getString("insectName")));
        List<Map<String, Object>> mapList = new ArrayList<>();
        for(String key : insectNameMapList.keySet()){
            Integer num = insectNameMapList.get(key).stream().map(x -> x.getInteger("num")).reduce(0, Integer::sum);
            Map<String, Object> map = new HashMap<>();
            map.put("insectName", key);
            map.put("num", num);
            mapList.add(map);
        }
        List<Date> timeList = insectAnalyseList.stream().map(x -> x.getDate("time")).sorted(Date::compareTo).collect(Collectors.toList());
        HashMap<String, Object> map = new HashMap();
        map.put("minTime", CollectionUtils.isEmpty(timeList) ? null : timeList.get(0));
        map.put("maxTime", CollectionUtils.isEmpty(timeList) ? null : timeList.get(timeList.size() - 1));
        map.put("analyseList", mapList);
        return map;
    }


    // 对数据进行分组并取最近时间的数据    当单一传感器出现问题时它的采集时间就是很久以前的时间
    public static List<ShiJiRuiTong> group(List<ShiJiRuiTong> dataList){
        Map<String, List<ShiJiRuiTong>> listMap = dataList.stream().collect(Collectors.groupingBy(ShiJiRuiTong::getParamName));
        List<ShiJiRuiTong> list = new ArrayList<>();
        for (String key : listMap.keySet()){
            List<ShiJiRuiTong> shiJiRuiTongs = listMap.get(key).stream().map(x -> {
                try {
                    x.setCreateTime(DATE_TIME_FORMAT.parse(x.getCtime()));
                } catch (ParseException e) {
                    x.setCreateTime(new Date());
                }
                return x;
            }).sorted(Comparator.comparing(ShiJiRuiTong::getCreateTime).reversed()).collect(Collectors.toList());
            list.add(shiJiRuiTongs.get(0));
        }
        return list;
    }
    public static List<SDRKData> groupSDRK(List<SDRKData> dataList){
        Map<String, List<SDRKData>> listMap = dataList.stream().collect(Collectors.groupingBy(SDRKData::getParamName));
        List<SDRKData> list = new ArrayList<>();
        for (String key : listMap.keySet()){
            list.add(listMap.get(key).stream().sorted(Comparator.comparing(SDRKData::getCtime).reversed()).collect(Collectors.toList()).get(0));
        }
        return list;
    }
    public static List<FruitData> groupFruit(List<FruitData> dataList){
        Map<String, List<FruitData>> listMap = dataList.stream().collect(Collectors.groupingBy(FruitData::getVariety));
        List<FruitData> list = new ArrayList<>();
        for (String key : listMap.keySet()){
            list.add(listMap.get(key).stream().sorted(Comparator.comparing(FruitData::getCreateTime).reversed()).collect(Collectors.toList()).get(0));
        }
        return list;
    }


    public JSONObject getNowData(String devId, String devType) {
        Equipment equipment = equipmentService.getById(devId);
        if(equipment == null){
            equipment = equipmentService.findBySerialAndCompanyId(devId, UserAuthUtil.getLoginUser().getCompanyId());
        }
        Assert.isFalse(equipment == null, () -> new BusinessException("该设备不存在"));
        List<Equipment> equipmentList = equipmentService.findByCompanyId(equipment.getCompanyId());
        JSONObject jsonObject = new JSONObject();
        if("气象监测站".equals(devType) || ("气象监测".equals(devType)) )
            devType = EQU_TYPE_ENV;
        if("土壤墒情站".equals(devType))
            devType = EQU_TYPE_SOIL;
        if("虫情测报仪".equals(devType))
            devType = EQU_TYPE_INSECT;
        if (EQU_MANUFACTURER_SJRT.equals(equipment.getManufacturer())) {
            // devType 气象数据  土壤数据  虫情监控 水质 杀虫灯 摄像机
            if (("气象监测站".equals(devType) || EQU_TYPE_ENV.equals(devType)) ||
                    ("土壤墒情站".equals(devType) || EQU_TYPE_SOIL.equals(devType)) ||
                    EQU_TYPE_KILL_INSECT.equals(devType) || EQU_TYPE_WATER.equals(devType)) {
//                String type = "气象监测站".equals(devType) ? EQU_TYPE_ENV : "土壤墒情站".equals(devType) ? EQU_TYPE_SOIL : EQU_TYPE_KILL_INSECT.equals(devType) ? EQU_TYPE_KILL_INSECT : EQU_TYPE_WATER;
//                jsonObject.put("data", shiJiRuiTongDao.getLast(equipment.getId()));
//                jsonObject.put("data", group(shiJiRuiTongDao.getLast(equipment.getId(), 30)));
//                jsonObject.put("devList", equipmentList.stream().filter(x -> devType.equals(x.getType())).collect(Collectors.toList()));
                Object data = dataMap.get(equipment.getId());
                jsonObject.put("data", data == null ? customParamSort(group(shiJiRuiTongDao.getLast(equipment.getId(), 30)), equipment) : customParamSort(data, equipment));
//                return jsonObject;
            } else if ("虫情测报仪".equals(devType) || EQU_TYPE_INSECT.equals(devType)) {
//                List<ShiJiRuiTong> insectHistoryData = getDevData.getInsectHistoryData(equipment.getSerial(), LocalDate.now().minusDays(1).toString(), LocalDate.now().toString())
//                        .stream().sorted(Comparator.comparing(ShiJiRuiTong::getVal).reversed()).limit(10).collect(Collectors.toList());
                List<ShiJiRuiTong> insectHistoryData = shiJiRuiTongDao.getLast(equipment.getId(), 30);
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                for (ShiJiRuiTong shiJiRuiTong : insectHistoryData) {
                    String time = LocalDateTime.parse(shiJiRuiTong.getVal().split("\\.")[0].replace("T", " "), formatter).format(formatter);
                    shiJiRuiTong.setVal(time);
                }
                jsonObject.put("data", insectHistoryData);
//                return jsonObject;
            }
        }
        if (EQU_MANUFACTURER_KB.equals(equipment.getManufacturer()) && EQU_TYPE_ENV.equals(devType)) {
//            List<KeBaiData> keBaiDataList = keBaiGetData.getAllDataByUser(equipment.getAppKey(), equipment.getAppSecret()).stream()
//                    .filter(x -> equipment.getSerial().equals(x.getNodecode())).collect(Collectors.toList());
//            for (KeBaiData keBaiData : keBaiDataList) {
//                ShiJiRuiTong sjrt = new ShiJiRuiTong();
//                sjrt.setCtime(keBaiData.getThattime().toString());
//                sjrt.setEquipmentId(equipment.getId());
//                sjrt.setParamVal(keBaiData.getSenval());
//                sjrt.setParamName(keBaiData.getSensorname());
//                sjrt.setParamUnit(keBaiData.getUnit());
//                envDataList.add(sjrt);
//            }
            Object data = dataMap.get(equipment.getId());
            jsonObject.put("data", data == null ? customParamSort(group(JSONArray.parseArray(JSONObject.toJSONString(keBaiDao.getLast(equipment.getId(), 25)), ShiJiRuiTong.class)), equipment) :
                    customParamSort(data, equipment));
//            return jsonObject;
        }
        if (EQU_MANUFACTURER_XFX.equals(equipment.getManufacturer())) {
//            JSONObject result = JSONObject.parseObject(HttpUtil.getDataFromUrl(url + equipment.getSerial()));
//            JSONArray jsonArray = result.getJSONArray("entity");
//            for (Object obj : jsonArray) {
//                JSONObject json = (JSONObject) obj;
//                ShiJiRuiTong sjrt = new ShiJiRuiTong();
//                sjrt.setCtime(json.getString("datetime"));
//                sjrt.setEquipmentId(equipment.getId());
//                sjrt.setParamVal(json.getString("eValue"));
//                sjrt.setParamName(json.getString("eName"));
//                sjrt.setParamUnit(json.getString("eUnit"));
//                envDataList.add(sjrt);
//            }
            Object data = dataMap.get(equipment.getId());
            jsonObject.put("data", data == null ? customParamSort(group(JSONArray.parseArray(JSONObject.toJSONString(xinFengXiangDao.getLast(equipment.getId(), 25)), ShiJiRuiTong.class)),
                    equipment) : customParamSort(data, equipment));
//            return jsonObject;
        }
        if (EQU_MANUFACTURER_OKQ.equals(equipment.getManufacturer())) {
            Object data = dataMap.get(equipment.getId());
            jsonObject.put("data", data == null ? customParamSort(group(JSONArray.parseArray(JSONObject.toJSONString(okqEnvDataDao.getLast(equipment.getId(), 25)), ShiJiRuiTong.class)),
                    equipment) : customParamSort(data, equipment));
        }
        List<Equipment> devList = devMap.get(equipment.getCompanyId());
        String type = devType;
        jsonObject.put("devList", CollectionUtils.isEmpty(devList) ? equipmentList.stream().filter(x -> type.equals(x.getType())).collect(Collectors.toList()) : devList.stream().filter(x -> type.equals(x.getType())).collect(Collectors.toList()));
        return jsonObject;
//        throw new BusinessException("参数错误");
    }



    public List<ShiJiRuiTong> getHistoryDevData(String devId, String paramName, String startTime, String endTime){
        Equipment equipment = equipmentService.getById(devId);
        if(equipment == null){
            equipment = equipmentService.findBySerialAndCompanyId(devId, UserAuthUtil.getLoginUser().getCompanyId());
        }
        Assert.isFalse(equipment == null, () -> new BusinessException("该设备不存在"));
        if(EQU_MANUFACTURER_SJRT.equals(equipment.getManufacturer())){
            return shiJiRuiTongDao.getHistoryData(devId, paramName, startTime, endTime);
        }else if(EQU_MANUFACTURER_XFX.equals(equipment.getManufacturer())){
            return genXFXSjrtList(xinFengXiangDao.getHistoryData(devId, paramName, startTime, endTime));
        }else if(EQU_MANUFACTURER_KB.equals(equipment.getManufacturer())){
            return genKBSjrtList(keBaiDao.getHistoryData(devId, paramName, startTime, endTime));
        }
        throw new BusinessException("设备厂商不存在");
    }




    public Object getHistoryData(String devId, String devType, String startTime, String endTime, Integer page, Integer pageSize, String type) {
        Equipment equipment = equipmentService.findByDevId(devId);
        if(StringUtils.isNotBlank(startTime))
            startTime = startTime + " 00:00:00";
        if(StringUtils.isNotBlank(endTime))
            endTime = endTime + " 23:59:59";
        if (EQU_MANUFACTURER_SJRT.equals(equipment.getManufacturer())) {
            if (EQU_TYPE_KILL_INSECT.equals(devType)) {
                if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime))
                    return shiJiRuiTongDao.getHistoryData(devId, startTime, endTime);
                else
                    return pageSize == null ? shiJiRuiTongDao.getHistoryData(devId) : shiJiRuiTongDao.getKillHistoryData(devId, pageSize);
            }
            if ("气象监测站".equals(devType) || EQU_TYPE_ENV.equals(devType)) {
                if("fruit".equals(type)){
                    if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
                        return genResult(shiJiRuiTongDao.getHistoryData(devId, startTime, endTime).stream().collect(Collectors.groupingBy(ShiJiRuiTong::getParamName)));
                    } else {
                        return genResult(shiJiRuiTongDao.getHistoryData(devId).stream().collect(Collectors.groupingBy(ShiJiRuiTong::getParamName)));
                    }
                }else {
                    if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
                        return genResult(shiJiRuiTongDao.getHistoryData(devId, startTime, endTime).stream().collect(Collectors.groupingBy(ShiJiRuiTong::getParamName)));
                    } else {
                        return genResult(shiJiRuiTongDao.getHistoryData(devId).stream().collect(Collectors.groupingBy(ShiJiRuiTong::getParamName)));
                    }
                }
            } else if ("土壤墒情站".equals(devType) || EQU_TYPE_SOIL.equals(devType)) {
                List<ShiJiRuiTong> soilHistoryList;
                if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime))
                    soilHistoryList = shiJiRuiTongDao.getHistoryData(devId, startTime, endTime);
                else
                    soilHistoryList = shiJiRuiTongDao.getHistoryData(devId);
                List<JSONObject> list = genResult(soilHistoryList.stream().filter(x -> x.getParamName().contains("土壤温度") || x.getParamName().contains("土壤湿度")).collect(Collectors.groupingBy(ShiJiRuiTong::getParamName)));
                List<JSONObject> list2 = genResult(soilHistoryList.stream().filter(x -> !x.getParamName().contains("土壤温度") && !x.getParamName().contains("土壤湿度")).collect(Collectors.groupingBy(ShiJiRuiTong::getParamName)));
                list.addAll(list2);
                return list;
            } else if ("虫情测报仪".equals(devType) || EQU_TYPE_INSECT.equals(devType)) {
                Pageable pageable = PageRequest.of(page - 1, pageSize);
                if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
                    return shiJiRuiTongDao.getHistoryData(devId, startTime, endTime, pageable);
                } else {
                    return shiJiRuiTongDao.getHistoryData(equipment.getId(), pageable);
                }
            }
        } else if (EQU_MANUFACTURER_XFX.equals(equipment.getManufacturer())) {
            if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
                List<ShiJiRuiTong> shiJiRuiTongList = genXFXSjrtList(xinFengXiangDao.getHistoryData(equipment.getId(), startTime, endTime));
                return genResult(shiJiRuiTongList.stream().collect(Collectors.groupingBy(ShiJiRuiTong::getParamName)));
            } else {
                List<ShiJiRuiTong> shiJiRuiTongList = genXFXSjrtList(xinFengXiangDao.getHistoryData(equipment.getId()));
                return genResult(shiJiRuiTongList.stream().collect(Collectors.groupingBy(ShiJiRuiTong::getParamName)));
            }
        }else if(EQU_MANUFACTURER_OKQ.equals(equipment.getManufacturer())){
            if ("虫情测报仪".equals(devType) || EQU_TYPE_INSECT.equals(devType)) {
                Pageable pageable = PageRequest.of(page - 1, pageSize);
                Page<OKQData> historyDataPage;
                if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
                    historyDataPage = okqDataDao.getHistoryData(devId, startTime, endTime, pageable);
                } else {
                    historyDataPage = okqDataDao.getHistoryData(equipment.getId(), pageable);
                }
                List<OKQData> dataList = historyDataPage.getContent();
                for(OKQData okqData : dataList){
                    okqData.setKey(StringUtils.isBlank(okqData.getExhibitionPath()) ? okqData.getPictureUrl() : okqData.getExhibitionPath());
                }
                return new PageImpl<OKQData>(dataList, pageable, historyDataPage.getTotalElements());
            }
            if(EQU_TYPE_ENV.equals(devType)){
                if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
                    List<ShiJiRuiTong> shiJiRuiTongList = genOKQSjrtList(okqEnvDataDao.getHistoryData(equipment.getId(), startTime, endTime));
                    return genResult(shiJiRuiTongList.stream().collect(Collectors.groupingBy(ShiJiRuiTong::getParamName)));
                } else {
                    List<ShiJiRuiTong> shiJiRuiTongList = genOKQSjrtList(okqEnvDataDao.getHistoryData(equipment.getId()));
                    return genResult(shiJiRuiTongList.stream().collect(Collectors.groupingBy(ShiJiRuiTong::getParamName)));
                }
            }
        } else if (EQU_MANUFACTURER_KB.equals(equipment.getManufacturer()) && EQU_TYPE_ENV.equals(devType)) {
            if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
                List<ShiJiRuiTong> shiJiRuiTongList = genKBSjrtList(keBaiDao.getHistoryData(equipment.getId(), startTime, endTime));
                return genResult(shiJiRuiTongList.stream().collect(Collectors.groupingBy(ShiJiRuiTong::getParamName)));
            } else {
                List<ShiJiRuiTong> shiJiRuiTongList = genKBSjrtList(keBaiDao.getHistoryData(equipment.getId()));
                return genResult(shiJiRuiTongList.stream().collect(Collectors.groupingBy(ShiJiRuiTong::getParamName)));
            }
        }
        throw new BusinessException("参数错误");
    }




    public DevThreshold saveThreshold(DevThreshold devThreshold) {
        if(StringUtils.isBlank(devThreshold.getId())){
            DevThreshold devThreshold1 = devThresholdDao.getByCompIdAndEquIdAndType(devThreshold.getCompId(), devThreshold.getEquId(), devThreshold.getType());
            if(Objects.nonNull(devThreshold1)){
                throw new BusinessException("该参数已有阈值");
            }
        }
        return devThresholdDao.save(devThreshold);
    }

    public Object findAll(String companyId) {
        List<BaseSoilView> baseSoilViews = baseSoilService.findinitAll2(StringUtils.isBlank(companyId) ? UserAuthUtil.getLoginUser().getCompanyId() : companyId);
        for (BaseSoilView baseSoilView : baseSoilViews) {
            if (2 == baseSoilView.getType()) {
                List<Plant> plantList = plantDao.findBySoilId(baseSoilView.getId());
                for (Plant plant : plantList) {
                    plant.setFarmList(farmDao.findByPlantId(plant.getId()));
                }
                baseSoilView.setPlantList(plantList);
            }
        }
        return baseSoilViews;
    }


    public List<Equipment> getDevList(String companyId, String devType) {
        List<Equipment> devList = new ArrayList<>();
        String type = devType;
        if("摄像头".equals(devType))
            devType = EQU_TYPE_VIDEO;
        List<Equipment> videoList = videoDevMap.get(companyId);
        if (CollectionUtils.isNotEmpty(videoList))
            devList.addAll(videoList);
        else
            devList.addAll(equipmentDao.findByTypeAndCompanyId(EQU_TYPE_VIDEO, companyId));
        if(StringUtils.isNotBlank(devType) && EQU_TYPE_VIDEO.equals(devType)){
            return devList;
        }
        List<Equipment> equipmentList = DevState.devMap.get(companyId);
        if (CollectionUtils.isNotEmpty(equipmentList)) {
            devList.addAll(equipmentList);
        } else
            devList.addAll(equipmentDao.findByTypeAndCompanyId(devType, companyId));
        if (StringUtils.isNotBlank(type))
            return devList.stream().filter(x -> type.equals(x.getType())).collect(Collectors.toList());
        else
            return devList;
    }

    public JSONObject getVideoDevList(String companyId, Integer pageNum, Integer pageSize, String group, String name) {
        JSONObject result = new JSONObject();
        List<Equipment> equipmentList = videoDevMap.get(companyId);
        if(CollectionUtils.isNotEmpty(equipmentList))
            equipmentList = videoDevMap.get(companyId).stream().collect(Collectors.toList());
        else
            equipmentList =  equipmentDao.findByTypeAndCompanyId(EQU_TYPE_VIDEO, companyId);
        if(StringUtils.isNotBlank(group)){
            equipmentList = equipmentList.stream().filter(x -> group.equals(x.getGroup())).collect(Collectors.toList());
        }
        if(CollectionUtils.isEmpty(equipmentList)){
            result.put("totalNum", 0);
            result.put("totalPage", 0);
            result.put("dataList", new ArrayList<>());
        }
        if(StringUtils.isNotBlank(name)){
            equipmentList = equipmentList.stream().filter(x -> x.getName().contains(name)).collect(Collectors.toList());
        }
        int size = equipmentList.size();
        result.put("totalNum", size);
        result.put("totalPage", calculateTotalPages(equipmentList, pageSize));
        if(pageNum != null && pageSize != null){
            equipmentList = equipmentList.stream()
                    .skip((pageNum - 1) * pageSize)
                    .limit(pageSize)
                    .collect(Collectors.toList());
        }
        result.put("dataList", equipmentList);
        return result;
    }


    public Set<String> getDevGroupList(String companyId, String devType) {
        List<Equipment> devList = getDevList(companyId, devType);
        if(CollectionUtils.isNotEmpty(devList))
            return devList.stream().filter(x -> StringUtils.isNotBlank(x.getGroup())).collect(Collectors.groupingBy(Equipment::getGroup)).keySet();
        return Collections.emptySet();
    }


    public static <T> int calculateTotalPages(List<T> items, int pageSize) {
        int totalItems = items.size();
        int totalPages = totalItems / pageSize;
        if (totalItems % pageSize != 0) {
            totalPages++;
        }
        return totalPages;
    }



    public List<DevThreshold> getByEquId(String companyId, String serial) {
        List<DevThreshold> devThresholdList = devThresholdDao.getByCompIdAndEquId(companyId, serial);
        // 第一次查询没有则生成
        if(CollectionUtils.isEmpty(devThresholdList)){
            Equipment equipment = equipmentService.findBySerialAndCompanyId(serial, companyId);
            Assert.isFalse(equipment == null, () -> new BusinessException("设备不存在"));
            List<JSONObject> paramNameList = new ArrayList<>();
            if(EQU_MANUFACTURER_SJRT.equals(equipment.getManufacturer())){
                paramNameList = shiJiRuiTongDao.getParamNameList(equipment.getId());
            }else if(EQU_MANUFACTURER_XFX.equals(equipment.getManufacturer())){
                paramNameList = xinFengXiangDao.getParamNameList(equipment.getId());
            }else if(EQU_MANUFACTURER_KB.equals(equipment.getManufacturer())){
                paramNameList = keBaiDao.getParamNameList(equipment.getId());
            } else if(EQU_MANUFACTURER_SDRK.equals(equipment.getManufacturer())){
                paramNameList = sdrkDataDao.getParamNameList(equipment.getId());
            }else if(EQU_MANUFACTURER_OKQ.equals(equipment.getManufacturer())){
                paramNameList = okqEnvDataDao.getParamNameList2(equipment.getId());
            }
            for(JSONObject json : paramNameList){
                devThresholdList.add(new DevThreshold(json.getString("paramName"), json.getString("paramName"), serial, companyId, json.getString("paramUnit")));
            }
            devThresholdDao.saveAll(devThresholdList);
        }
        return devThresholdList;
    }




    public List<DevAlarm> findAlarmNotPage(DevAlarm devAlarm) {
        return devAlarmDao.findAll((Root<DevAlarm> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
            return genAlarmPred(devAlarm, root, cb);
        });
    }


    public Page<DevAlarm> findAlarmList(DevAlarm devAlarm) {
        Pageable pageable = PageRequest.of(devAlarm.getPage(), devAlarm.getPageSize(), Sort.Direction.DESC, "createTime");
        return devAlarmDao.findAll((Root<DevAlarm> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
            return genAlarmPred(devAlarm, root, cb);
        }, pageable);
    }




    public Predicate genAlarmPred(DevAlarm devAlarm, Root<DevAlarm> root, CriteriaBuilder cb){
        List<Predicate> list = new ArrayList<>();
        if (StringUtils.isNotBlank(devAlarm.getParamName()))
            list.add(cb.like(root.get("paramName"), "%" + devAlarm.getParamName() + "%"));
        if (StringUtils.isNotBlank(devAlarm.getDevName()))
            list.add(cb.like(root.get("devName"), "%" + devAlarm.getDevName() + "%"));
        if (StringUtils.isNotBlank(devAlarm.getDevId()))
            list.add(cb.equal(root.get("devId"), devAlarm.getDevId()));
        if (StringUtils.isNotBlank(devAlarm.getAlarmType()))
            list.add(cb.equal(root.get("alarmType"), devAlarm.getAlarmType()));
        if (StringUtils.isNotBlank(devAlarm.getBaseSoilName()))
            list.add(cb.equal(root.get("baseSoilName"), devAlarm.getBaseSoilName()));
        if (StringUtils.isNotBlank(devAlarm.getStartTime()) && StringUtils.isNotBlank(devAlarm.getEndTime()))
            list.add(cb.between(root.get("createTime"), devAlarm.getStartTime(), devAlarm.getEndTime()));
        if(StringUtils.isNotBlank(devAlarm.getHandleState())){
            list.add(cb.equal(root.get("handleState"), devAlarm.getHandleState()));
        }
        if(StringUtils.isNotBlank(devAlarm.getCompId())){
            list.add(cb.equal(root.get("compId"), devAlarm.getCompId()));
        }
        return cb.and(list.toArray(new Predicate[list.size()]));
    }






    public void handle(List<String> idList) {
        devAlarmDao.handle(idList);
    }

    public List<String> getAlarmBaseSoil(String companyId) {
        if(StringUtils.isBlank(companyId)){
            companyId = UserAuthUtil.getLoginUser().getCompanyId();
        }
        return devAlarmDao.getAlarmBaseSoil(companyId);
    }





    public JSONObject getLineData(String devId, String startTime, String endTime) {
        Equipment equipment = equipmentDao.findById(devId);
        if(equipment == null)
            throw new BusinessException("该设备不存在");
        List<String> lineList;
        if (EQU_MANUFACTURER_SJRT.equals(equipment.getManufacturer())) {
            if(StringUtils.isBlank(startTime))
                lineList = shiJiRuiTongDao.getByCreateTime(equipment.getId());
            else
                lineList = shiJiRuiTongDao.getByCreateTime(equipment.getId(), startTime, endTime);
            return getAssembleResult(lineList, EQU_TYPE_SOIL.equals(equipment.getType()) ? sjrtSoilParam : sjrtEnvParam);
        }else if (EQU_MANUFACTURER_XFX.equals(equipment.getManufacturer())) {
            if(StringUtils.isBlank(startTime))
                lineList = xinFengXiangDao.getByCreateTime(equipment.getId());
            else
                lineList = xinFengXiangDao.getByCreateTime(equipment.getId(), startTime, endTime);
            return getAssembleResult(lineList, xfxEnvParam);
        } else if (EQU_MANUFACTURER_OKQ.equals(equipment.getManufacturer())) {
            if(StringUtils.isBlank(startTime))
                lineList = okqEnvDataDao.getByCreateTime(equipment.getId());
            else
                lineList = okqEnvDataDao.getByCreateTime(equipment.getId(), startTime, endTime);
            return getAssembleResult(lineList, okqEnvParam);
        }else if (EQU_MANUFACTURER_KB.equals(equipment.getManufacturer())) {
            if(StringUtils.isBlank(startTime))
                lineList = keBaiDao.getByCreateTime(equipment.getId());
            else
                lineList = keBaiDao.getByCreateTime(equipment.getId(), startTime, endTime);
            return getAssembleResult(lineList, kbEnvParam);
        }else
            throw new BusinessException("设备厂商不存在");
    }




    public void exportLineData(String devId, String startTime, String endTime, HttpServletResponse response) throws IOException {
        Equipment equipment = equipmentDao.findById(devId);
        if(equipment == null)
            throw new BusinessException("该设备不存在");
        List<String> lineList;
        if (EQU_MANUFACTURER_SJRT.equals(equipment.getManufacturer())) {
            if(StringUtils.isBlank(startTime))
                lineList = shiJiRuiTongDao.getByCreateTime(equipment.getId());
            else
                lineList = shiJiRuiTongDao.getByCreateTime(equipment.getId(), startTime, endTime);
//            result = getTable(getAssembleResult(lineList, EQU_TYPE_SOIL.equals(equipment.getType()) ? sjrtSoilParam : sjrtEnvParam));
            JSONObject jsonObject = getAssembleResult(lineList, EQU_TYPE_SOIL.equals(equipment.getType()) ? sjrtSoilParam : sjrtEnvParam);

            if(EQU_TYPE_SOIL.equals(equipment.getType())){
                List<SJRTSoilDTO> dataList = JSONObject.parseArray(jsonObject.getString("dataList"), SJRTSoilDTO.class);
                EasyPoiUtils.exportExcel(dataList, "土壤监测数据", "土壤监测数据", SJRTSoilDTO.class, "土壤监测数据", response);
            }else {
                List<SJRTEnvDTO> dataList = JSONObject.parseArray(jsonObject.getString("dataList"), SJRTEnvDTO.class);
                EasyPoiUtils.exportExcel(dataList, "气象监测数据", "气象监测数据", SJRTEnvDTO.class, "气象监测数据", response);
            }
        }else if (EQU_MANUFACTURER_XFX.equals(equipment.getManufacturer())) {
            if(StringUtils.isBlank(startTime))
                lineList = xinFengXiangDao.getByCreateTime(equipment.getId());
            else
                lineList = xinFengXiangDao.getByCreateTime(equipment.getId(), startTime, endTime);
//            result = getTable(getAssembleResult(lineList, xfxEnvParam));
            JSONObject jsonObject = getAssembleResult(lineList, xfxEnvParam);
            List<XFXEnvDTO> dataList = JSONObject.parseArray(jsonObject.getString("dataList"), XFXEnvDTO.class);
            EasyPoiUtils.exportExcel(dataList, "气象监测数据", "气象监测数据", SJRTSoilDTO.class, "气象监测数据", response);
        } else if (EQU_MANUFACTURER_KB.equals(equipment.getManufacturer())) {
            if(StringUtils.isBlank(startTime))
                lineList = keBaiDao.getByCreateTime(equipment.getId());
            else
                lineList = keBaiDao.getByCreateTime(equipment.getId(), startTime, endTime);
//            result = getTable(getAssembleResult(lineList, kbEnvParam));
            JSONObject jsonObject = getAssembleResult(lineList, kbEnvParam);
            List<KBEnvDTO> dataList = JSONObject.parseArray(jsonObject.getString("dataList"), KBEnvDTO.class);
            EasyPoiUtils.exportExcel(dataList, "气象监测数据", "气象监测数据", SJRTSoilDTO.class, "气象监测数据", response);
        }else{
            throw new BusinessException("设备厂商不存在");
        }

        // 定义标题和sheet名称
//        ExportParams exportParams = new ExportParams("监测数据", "监测数据");
//        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, (List<ExcelExportEntity>) result.get("columnList"), (List<Map<String, String>>)result.get("resultDataList"));
//        EasyPoiUtils.downLoadExcel("监测数据", response, workbook);
    }















    // 组合存在问题
    public JSONObject getTable(JSONObject jsonObject){
        List<ImmutableBiMap> titleList = (List<ImmutableBiMap>) jsonObject.get("title");
        List<JSONObject> dataList = (List<JSONObject>) jsonObject.get("dataList");
        List<Map<String, String>> resultDataList = new ArrayList();
        List<ExcelExportEntity> columnList = new ArrayList<ExcelExportEntity>();
        for(ImmutableBiMap map : titleList){
            String columnName = String.valueOf(map.get("key"));
            String columnKey = String.valueOf(map.get("value"));
            ExcelExportEntity colEntity = new ExcelExportEntity(columnName, columnKey);
            colEntity.setNeedMerge(true);
            columnList.add(colEntity);
//            Map<String, String> columnMap = new HashMap<>();
//            for(JSONObject json : dataList){
//                columnMap.put(columnKey, json.getString(columnKey));
//                resultDataList.add(columnMap);
//            }
        }

        for(ExcelExportEntity entity : columnList){
            String key = String.valueOf(entity.getKey());
            for(JSONObject json : dataList){
                Map<String, String> columnMap = new HashMap<>();
                Set<String> keySet = json.keySet();
                for(String key1 : keySet){
//                    if(key.equals(key1)){
                        columnMap.put(key1, json.getString(key1));
                        resultDataList.add(columnMap);
//                    }
                }
            }
        }
        JSONObject object = new JSONObject();
        object.put("columnList", columnList);
        object.put("resultDataList", resultDataList.stream().distinct().collect(Collectors.toList()));
        return object;
    }






    public List<JSONObject> getByParamName(String devId, String paramName, String startTime, String endTime){
        Equipment equipment = equipmentDao.findById(devId);
        if(equipment == null)
            throw new BusinessException("该设备不存在");
        List<JSONObject> lineList;
        if (EQU_MANUFACTURER_SJRT.equals(equipment.getManufacturer())) {
            if(StringUtils.isBlank(startTime))
                lineList = shiJiRuiTongDao.getByParamName(equipment.getId(), paramName);
            else
                lineList = shiJiRuiTongDao.getByParamName(equipment.getId(), paramName, startTime, endTime);
        }else if (EQU_MANUFACTURER_XFX.equals(equipment.getManufacturer())) {
            if(StringUtils.isBlank(startTime))
                lineList = xinFengXiangDao.getByParamName(equipment.getId(), paramName);
            else
                lineList = xinFengXiangDao.getByParamName(equipment.getId(), paramName, startTime, endTime);
        } else if (EQU_MANUFACTURER_KB.equals(equipment.getManufacturer())) {
            if (StringUtils.isBlank(startTime))
                lineList = keBaiDao.getByParamName(equipment.getId(), paramName);
            else
                lineList = keBaiDao.getByParamName(equipment.getId(), paramName, startTime, endTime);
        }else
            throw new BusinessException("设备厂商不存在");
        return lineList;
    }

    public JSONObject getInfo() {
        JSONObject json = new JSONObject();
        List<JSONObject> fruitList = companyDao.getFruit();
        long normalFruitNum = fruitList.stream().filter(x -> "普通果园".equals(x.getString("fruitType"))).count();
        int fruitNum = fruitList.size();
        List<Plant> plantList = plantDao.findAll();
        Double areaAll = plantList.stream().map(x -> Double.valueOf(x.getPlantArea())).reduce(0D, Double::sum);
        Map<String, List<Plant>> listMap = plantList.stream().collect(Collectors.groupingBy(Plant::getPlantName));
        List<Map<String, String>> list = new ArrayList<>();
        for(String plantName : listMap.keySet()){
            Double area = listMap.get(plantName).stream().map(x -> Double.valueOf(x.getPlantArea())).reduce(0D, Double::sum);
            Map<String, String> map = new HashMap<>();
            map.put("plantName", plantName);
            map.put("ratio", MathUtils.percentage(area, areaAll));
            list.add(map);
        }
        json.put("normalFruitNum", normalFruitNum);                 // 普通果园数量
        json.put("wisdomFruitNum", fruitNum - normalFruitNum);      // 智慧果园数量
        json.put("fruitNum", fruitNum);                             // 果园总数
        json.put("fruitComp", fruitList);                           // 果园企业[name=企业名, fruitType=果园类型(1=普通果园  2=智慧果园)]
        json.put("news", articleDao.getIdNameTitleByState());       // 文章
        json.put("plantRatioList", list);                           // 种植品类占比
        json.put("areaAll", areaAll);                               // 总面积
        return json;
    }



    public List<Equipment> getEquListByCompId(String companyId) {
        if(StringUtils.isBlank(companyId)){
            companyId = "4028814b8b1d696f018b92b06250000c";
        }
        List<Equipment> devList = devMap.get(companyId).stream().collect(Collectors.toList());
        List<Equipment> videoList = videoDevMap.get(companyId);
        if(CollectionUtils.isEmpty(devList)){
            devList = equipmentDao.findDevListByCompanyId(companyId);
        }
        if(CollectionUtils.isEmpty(videoList)){
            videoList = equipmentDao.findVideoListByCompanyId(companyId);
        }
        if(CollectionUtils.isNotEmpty(devList))
            devList.addAll(videoList);
        else if(CollectionUtils.isNotEmpty(videoList))
            return videoList;
        return devList;
    }



    public List<SDRKData> getNwcDataList() {
        String companyId = "4028814b8b1d696f018b92b06250000c";
        List<Equipment> devList = devMap.get(companyId);
        if(CollectionUtils.isEmpty(devList))
            devList = equipmentDao.findByTypeAndCompanyId(EQU_TYPE_ENV, companyId);
        List<SDRKData> sdrkDataList = new ArrayList<>();
        for(Equipment equipment : devList){
            List<SDRKData> data = (List<SDRKData>) dataMap.get(equipment.getId());
            if(ObjectUtils.isEmpty(data)){
                data = groupSDRK(sdrkDataDao.getLast(equipment.getId(), 6));
            }
            sdrkDataList.addAll(data);
        }
        return sdrkDataList;
    }


    public JSONObject getHistoryByDevId(String equId, String startTime, String endTime) {
        JSONObject json = new JSONObject();
        Object dataList = dataMap.get(equId);
        json.put("nowData", dataList == null ? groupSDRK(sdrkDataDao.getLast(equId, 8)) : dataList);
        json.put("historyData", genSDRKResult(sdrkDataDao.getHistoryData(equId, startTime, endTime).stream().collect(Collectors.groupingBy(SDRKData::getParamName))));
        return json;
    }

    public JSONObject getDataById(String equId, String type) {
        JSONObject result = new JSONObject();
        List<JSONObject> data = new ArrayList<>();
        if(StringUtils.isNotBlank(type)){
            if("day".equals(type))
                data = sdrkDataDao.getDay();
            else if("week".equals(type))
                data = sdrkDataDao.getWeek();
            else if("month".equals(type))
                data = sdrkDataDao.getMonth();
            else
                throw new BusinessException("type参数不正确");
        }
        result.put("data", data);
        result.put("cnt", sdrkDataDao.count());
        Object dataObj = dataMap.get(equId);
        List<SDRKData> dataList = null;
        if(dataObj != null){
            dataList = (List<SDRKData>) dataObj;
        }
        if(CollectionUtils.isEmpty(dataList))
            result.put("dataList", groupSDRK(sdrkDataDao.getLast(equId, 6)));
        else
            result.put("dataList", dataList);
        return result;
    }

    public List<SDRKData> getDataByDeviceAddr(String deviceAddr) {
        Map<String, Object> param = new HashMap<>();
        param.put("loginName", "h230925yzc");
        param.put("password", "h230925yzc");
        String token = JSONObject.parseObject(HttpUtil.get(SDRK_GET_TOKEN, param)).getJSONObject("data").getString("token");

        Map<String, Object> map = new HashMap<>();
        map.put("deviceAddrs", deviceAddr);
        JSONArray jsonArray = JSONObject.parseObject(HttpUtil.createGet(SDRK_GET_DATA).header("authorization", token).form(map).execute().body()).getJSONArray("data");
        List<SDRKData> sdrkDataList = new ArrayList<>();
        for(Object obj : jsonArray){
            JSONObject json = JSONObject.parseObject(obj.toString());
            String deviceStatus = json.getString("deviceStatus");
            String devAddr = json.getString("deviceAddr");      // 设备序列号
            String time = DATE_TIME_FORMATTER.format(Instant.ofEpochMilli(json.getLong("timeStamp")).atZone(ZoneOffset.ofHours(8)).toLocalDateTime());
            String status = "normal".equals(deviceStatus) ? "1" : "offline".equals(deviceStatus) ? "0" : "alarming".equals(deviceStatus) ? "2" : "3";

            JSONArray dataItem = json.getJSONArray("dataItem");
            for(Object item : dataItem){
                JSONObject dataItemJson = JSONObject.parseObject(item.toString());
                JSONArray registerItem = dataItemJson.getJSONArray("registerItem");
                for(Object itemObj : registerItem){
                    JSONObject object = JSONObject.parseObject(itemObj.toString());
                    String registerName = object.getString("registerName");
                    Float val = object.getFloat("data");
                    String unit = object.getString("unit");
                    SDRKData sdrkData = new SDRKData();
                    sdrkData.setParamUnit(unit);
                    sdrkData.setParamVal(val);
                    sdrkData.setParamName(registerName);
                    sdrkData.setCtime(time);
                    sdrkData.setType("7");
                    sdrkDataList.add(sdrkData);
                }
            }
        }
        return sdrkDataList;
    }







    public JSONObject getDevState(String companyId) {
        JSONObject json = new JSONObject();
        List<Equipment> equList = new ArrayList<>();
        if(StringUtils.isBlank(companyId)){
            // 所有果园企业ID
            List<String> fruitIdList = companyDao.getFruitId();
            Map<String, List<Equipment>> videoDevMap = DevState.videoDevMap;
            for(String compId : videoDevMap.keySet()){
                if(fruitIdList.contains(compId))
                    equList.addAll(videoDevMap.get(compId));
            }
            Map<String, List<Equipment>> devMap = DevState.devMap;
            for(String compId : devMap.keySet()){
                if(fruitIdList.contains(compId))
                    equList.addAll(devMap.get(compId));
            }
        }
        else{
            equList.addAll(DevState.videoDevMap.get(companyId));
            equList.addAll(DevState.devMap.get(companyId));
        }
        Map<String, List<Equipment>> typeMapList = equList.stream().collect(Collectors.groupingBy(Equipment::getType));
        List<Map<String, Object>> maps = new ArrayList<>();
        for(String type : typeMapList.keySet()){
            Map<String, Object> map = new HashMap<>();
            List<Equipment> equipmentList = typeMapList.get(type);
            map.put("type", type);
            map.put("onlineNum", equipmentList.stream().filter(x -> "1".equals(x.getStatus())).count());
            map.put("totalNum", equipmentList.size());
            maps.add(map);
        }
        json.put("devCnt", equList.size());         // 设备总数
        json.put("devState", maps);                 // 在线情况 [type=类型, onlineNum=在线数量, totalNum=总数]
        return json;
    }




    public List<JSONObject> getDevNum(String type){
        if(StringUtils.isBlank(type))
            type = "果园";
        Map<String, String> map = townVillageMap.get(type);
        List<JSONObject> jsonList = new ArrayList<>();
        for(String key : map.keySet()){
            JSONObject json = genDevJson();
            json.put("name", key);
            List<Equipment> equipmentList = equipmentDao.findByCompanyIdList(Arrays.asList(map.get(key).split(",")));
            Map<String, List<Equipment>> listMap = equipmentList.stream().collect(Collectors.groupingBy(Equipment::getType));
            for(String equTypeKey : listMap.keySet()){
                json.put(equTypeKey, listMap.get(equTypeKey).size());
            }
            jsonList.add(json);
        }
        return jsonList;
    }




    public List<JSONObject> getPlant(String type){
        if(StringUtils.isBlank(type))
            type = "镇";
        List<JSONObject> resultList = new ArrayList<>();
        if("镇".equals(type) || "村".equals(type)){
            JSONObject param = new JSONObject();
            param.put("type", type);
            JSONArray jsonArray = restService.postJson(RestURL.CONTROL + "cms/findFruitTownList", param).getJSONArray("data");
            List<JSONObject> fruitTownList = groupByFruitTownName(jsonArray, type);
            for(JSONObject json : fruitTownList){
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("name", json.getString("name"));
                jsonObject.put("area", json.getString("area"));
                jsonObject.put("areaUnit", json.getString("areaUnit"));
                jsonObject.put("prod", json.getString("prodNum"));
                jsonObject.put("prodNumUnit", json.getString("prodNumUnit"));
                resultList.add(jsonObject);
            }
        }else {
            Map<String, String> map = townVillageMap.get(type);
            for(String key : map.keySet()){
                List<JSONObject> compNameProdList = companyDao.getNameProdByIds(Arrays.asList(map.get(key).split(",")));
                for(JSONObject json : compNameProdList){
                    Double area = plantDao.getAreaByCompanyId(json.getString("id")).stream().reduce(0D, Double::sum);
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("name", json.getString("abbreviation"));
                    jsonObject.put("area", area == 0 ? 0 : MathUtils.formatSix(area / 10000));
                    jsonObject.put("areaUnit", "万亩");
                    JSONObject fruitProd = JSONObject.parseObject(json.getString("fruitProd"));
                    jsonObject.put("prod", fruitProd == null ? 0 : fruitProd.getString("prodNum"));
                    jsonObject.put("prodNumUnit", "万吨");
                    resultList.add(jsonObject);
                }
            }
        }
        return resultList;
    }



    public List<JSONObject> getPlantInfo(String type, String name){
        if(StringUtils.isBlank(type))
            type = "镇";
        List<JSONObject> resultList = new ArrayList<>();
        if("镇".equals(type) || "村".equals(type)){
            HashMap<String, String> paramMap = new HashMap<>();
            paramMap.put("type", type);
            paramMap.put("name", name);
            JSONArray jsonArray = restService.getJson(RestURL.CONTROL + "cms/findFruitTownByNameType?name=" + name + "&type=" + type).getJSONArray("data");
            List<JSONObject> fruitTownList = groupByFruitTownName(jsonArray, type);
            for(JSONObject json : fruitTownList){
                JSONArray info = json.getJSONArray("info");
                if(info == null)
                    break;
                for(Object obj : info){
                    JSONObject jsonObject = new JSONObject();
                    JSONObject object = JSONObject.parseObject(obj.toString());
                    jsonObject.put("name", object.getString("plantName"));
                    jsonObject.put("unit", "亩");
                    jsonObject.put("area", MathUtils.formatSix(Double.valueOf(object.getString("area")) * 10000));
                    resultList.add(jsonObject);
                }
            }
        }else {
            Map<String, String> map = townVillageMap.get(type);
            for(String key : map.keySet()){
                if(!key.equals(name)){
                    continue;
                }
                String companyId = map.get(key);
                Map<String, List<Plant>> listMap = plantDao.findByCompanyId(companyId).stream().collect(Collectors.groupingBy(Plant::getPlantName));
                for(String plantNameKey : listMap.keySet()){
                    Double area = listMap.get(plantNameKey).stream().map(x -> Double.valueOf(x.getPlantArea())).reduce(0D, Double::sum);
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("name", plantNameKey);
                    jsonObject.put("unit", "亩");
//                    jsonObject.put("area", area == null ? 0 : MathUtils.formatSix(area / 10000));
                    jsonObject.put("area", area == null ? 0 : MathUtils.formatSix(area));
                    resultList.add(jsonObject);
                }
            }
        }
        return resultList;
    }








    public List<JSONObject> getPrice(String type, String startTime, String endTime){
        List<JSONObject> jsonList = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();
        String time = "";
        List<FruitData> listByType;
        if(StringUtils.isNotBlank(type)){
            if("周".equals(type))
                time = DATE_TIME_FORMATTER.format(LocalDateTime.of(now.minusDays(7).toLocalDate(), LocalTime.of(0, 0, 0)));
            if("月".equals(type))
                time = DATE_TIME_FORMATTER.format(LocalDateTime.of(now.minusDays(30).toLocalDate(), LocalTime.of(0, 0, 0)));
            if("半年".equals(type))
                time = DATE_TIME_FORMATTER.format(LocalDateTime.of(now.minusMonths(6).toLocalDate(), LocalTime.of(0, 0, 0)));
            listByType = fruitDataDao.getByType("1", time);
        }else {
            listByType = fruitDataDao.getByType("1", startTime, endTime);
        }
        if("半年".equals(type)){
            Map<String, Map<String, List<FruitData>>> mapMapList = listByType
                    .stream()
                    .collect(Collectors.groupingBy(FruitData::getVariety,
                                Collectors.groupingBy(x -> x.getCreateTime().substring(0, 7))));
            for(String varietyKey : mapMapList.keySet()){
                JSONObject json = new JSONObject();
                json.put("name", varietyKey);
                Map<String, List<FruitData>> mapList = mapMapList.get(varietyKey);
                List<JSONObject> list = new ArrayList<>();
                for(String timeKey : mapList.keySet()){
                    JSONObject object = new JSONObject();
                    FruitData fruitData = mapList.get(timeKey).get(0);
                    object.put("time", fruitData.getCreateTime().substring(0, 7).split("-")[1] + "月");
                    object.put("completeTime", fruitData.getCreateTime());
                    object.put("value", fruitData.getVal());
                    list.add(object);
                }
                json.put("data", list.stream().sorted(Comparator.comparing(x -> x.getDate("completeTime"))).collect(Collectors.toList()));
                jsonList.add(json);
            }
        }else {
            Map<String, List<FruitData>> listMap = listByType.stream().collect(Collectors.groupingBy(FruitData::getVariety));
            for(String varietyKey : listMap.keySet()){
                JSONObject json = new JSONObject();
                json.put("name", varietyKey);
                List<FruitData> fruitDataList = listMap.get(varietyKey);
                List<JSONObject> list = new ArrayList<>();
                for(FruitData fruitData : fruitDataList){
                    JSONObject object = new JSONObject();
                    object.put("time", fruitData.getCreateTime().substring(0, 10));
                    object.put("completeTime", fruitData.getCreateTime());
                    object.put("value", fruitData.getVal());
                    list.add(object);
                }
                json.put("data", list.stream().sorted(Comparator.comparing(x -> x.getDate("completeTime"))).collect(Collectors.toList()));
                jsonList.add(json);
            }
        }
        return jsonList;
    }







    public static Map<String, Map<String, String>> townVillageMap = new HashMap(){
        private static final long serialVersionUID = 5140056720976152281L;
        {
            Map<String, String> town = new HashMap<>();
            town.put("枣园镇", "4028814b89ae9d99018acfe9b8ee0043,4028814b89ae9d99018ab088f43b0032,4028814b8b1d696f018b92b06250000c");
            town.put("亭口镇", "4028814b89ae9d99018acf7d745c003d,4028814b89ae9d99018acfe6d4060040,4028814b8b1d696f018b8a23ff180004,4028814b8b1d696f018b8a2c9a260008");
            town.put("相公镇", "4028814b8b1d696f018b92b06250001");
            put("镇", town);

            Map<String, String> village = new HashMap<>();
            village.put("牛王村", "4028814b89ae9d99018acfe9b8ee0043,4028814b8b1d696f018b92b06250000c");
            village.put("郭村", "4028814b89ae9d99018ab088f43b0032");
            village.put("樊罗村", "4028814b89ae9d99018acf7d745c003d");
            village.put("路家村", "4028814b89ae9d99018acfe6d4060040,4028814b8b1d696f018b8a23ff180004");
            village.put("柴厂村", "4028814b8b1d696f018b8a2c9a260008");
            village.put("芋元村", "4028814b8b1d696f018b92b06250001");
            put("村", village);

            Map<String, String> fruit = new HashMap<>();
            fruit.put("乾富祥", "4028814b89ae9d99018ab088f43b0032");
            fruit.put("长凌", "4028814b89ae9d99018acf7d745c003d");
            fruit.put("三丰", "4028814b89ae9d99018acfe6d4060040");
            fruit.put("瑞杰", "4028814b89ae9d99018acfe9b8ee0043");
            fruit.put("庆丰源", "4028814b8b1d696f018b8a23ff180004");
            fruit.put("天恩", "4028814b8b1d696f018b8a2c9a260008");
//            fruit.put("牛王村", "4028814b8b1d696f018b92b06250000c");
//            fruit.put("芋元村", "4028814b8b1d696f018b92b06250001");
            put("果园", fruit);
        }};

    public JSONObject genDevJson(){
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("杀虫灯", 0);
        jsonObject.put("虫情监控", 0);
        jsonObject.put("气象传感", 0);
        jsonObject.put("土壤墒情", 0);
        jsonObject.put("摄像机", 0);
        return jsonObject;
    }




    public JSONObject  getHomeData(){
        JSONObject json = new JSONObject();
        List<JSONObject> fruitList = companyDao.getFruit();
        long normalFruitNum = fruitList.stream().filter(x -> "普通果园".equals(x.getString("fruitType"))).count();
        long compFruitNum = fruitList.stream().filter(x -> "公司".equals(x.getString("compType"))).count();
        long cooperativeNum = fruitList.stream().filter(x -> "合作社".equals(x.getString("compType"))).count();
        int fruitNum = fruitList.size();

        List<Map<String, Object>> list = new ArrayList<>();
        JSONObject data = restService.getJson(RestURL.CONTROL + "cms/findAllFruitTownExpert").getJSONObject("data");

        List<JSONObject> townList = groupByFruitTownName(data.getJSONArray("fruitTownList"), "镇");
        Double areaAll = townList.stream().map(x -> x.getDouble("area")).reduce(0D, Double::sum);
        JSONArray plantArray = new JSONArray();
        for(JSONObject item : townList){
            JSONArray info = item.getJSONArray("info");
            if(info != null){
                plantArray.addAll(info);
            }
        }
        Map<String, List<JSONObject>> listMap = plantArray.stream().map(x -> JSONObject.parseObject(JSONObject.toJSONString(x))).collect(Collectors.groupingBy(x -> x.getString("plantName")));
        for (String plantName : listMap.keySet()) {
            Double area = listMap.get(plantName).stream().map(x -> x.getDouble("area")).reduce(0D, Double::sum);
            Map<String, Object> map = new HashMap<>();
            map.put("plantName", plantName);
            map.put("area", Double.valueOf(MathUtils.formatFour(area)));
            map.put("unit", "万亩");
            map.put("ratio", MathUtils.percentage(area, areaAll));
            list.add(map);
        }

//        List<Plant> plantList = plantDao.findAll();
//        Double areaAll = plantList.stream().map(x -> Double.valueOf(x.getPlantArea())).reduce(0D, Double::sum);
//        Map<String, List<Plant>> listMap = plantList.stream().collect(Collectors.groupingBy(Plant::getPlantName));
//        for(String plantName : listMap.keySet()){
//            Double area = listMap.get(plantName).stream().map(x -> Double.valueOf(x.getPlantArea())).reduce(0D, Double::sum);
//            Map<String, Object> map = new HashMap<>();
//            map.put("plantName", plantName);
//            map.put("area", area);
//            map.put("ratio", MathUtils.percentage(area, areaAll));
//            list.add(map);
//        }



        JSONArray expertList = data.getJSONArray("expertList");
        Map<String, List<JSONObject>> typeMap = expertList.stream().map(x -> JSONObject.parseObject(JSONObject.toJSONString(x))).collect(Collectors.groupingBy(x -> x.getString("type")));
        List<Map<String, Object>> mapList = new ArrayList<>();
        for(String key : typeMap.keySet()){
            Map<String, Object> map = new HashMap<>();
            map.put("type", key);
            map.put("num", typeMap.get(key).size());
            mapList.add(map);
        }
        //  设备信息
        Long devTotal = 0L;
        Long onlineNum = 0L;
        int alarmDevNum = devThresholdDao.getAlarmDevNum().size();
        long alarmNum = devAlarmDao.count();
        List<List<Equipment>> equipmentList = new ArrayList<>();
        List<List<Equipment>> devList = new ArrayList(devMap.values());
        List<List<Equipment>> videoList = new ArrayList(videoDevMap.values());
        if(CollectionUtils.isNotEmpty(devList)){
            equipmentList.addAll(devList);
        }
        if(CollectionUtils.isNotEmpty(videoList)){
            equipmentList.addAll(videoList);
        }
        if(CollectionUtils.isEmpty(equipmentList)){
            devTotal = equipmentDao.cntNotVr();
            onlineNum = devTotal;
        }else {
            for(List<Equipment> equList : equipmentList){
                for(Equipment equipment : equList){
                    devTotal += 1;
                    if("1".equals(equipment.getStatus()))
                        onlineNum += 1;
                }
            }
        }

        json.put("expertTypeMap", mapList);                                      // 专家类型数量
        json.put("expertNum", expertList.size());                                // 专家总数

        json.put("normalFruitNum", normalFruitNum);                             // 普通果园数量
        json.put("wisdomFruitNum", fruitNum - normalFruitNum);                  // 智慧果园数量
        json.put("fruitNum", fruitNum);                                         // 果园总数

        json.put("compFruitNum", compFruitNum);                                 // 公司 数量
        json.put("cooperativeNum", cooperativeNum);                             // 合作社 数量
        json.put("person", fruitNum - (compFruitNum + cooperativeNum));         // 私人 数量

        json.put("news", articleDao.getIdNameTitleByState());                   // 园区动态 最新文章资讯
        json.put("fruitComp", fruitList);                                       // 果园企业[name=企业名, fruitType=果园类型(普通果园  智慧果园), address=地址, fruitProd=产量产值...]
        json.put("plantRatioList", list);                                       // 种植品类占比
        json.put("areaAll", MathUtils.formatFour(areaAll));  // 总面积

        json.put("coverCompNum", fruitNum);                                     // 覆盖企业数
        json.put("coverCompNumRatio", "100%");                                  // 入网企业覆盖数
        json.put("devTotal", devTotal);                                         // 设备总数
        json.put("onlineNum", onlineNum);                                       // 在线数量
        json.put("onlineRatio", MathUtils.percentage(onlineNum, devTotal));     // 在线占比
        json.put("alarmDevNum", alarmDevNum);                                   // 预警设备数
        json.put("alarmNum", alarmNum);                                         // 预警信息数量

        json.put("fruitTownList", townList);         // 果园镇列表
        json.put("sale", groupFruit(fruitDataDao.getListByType("2", 10)));  // 销售数据

        return json;
    }


    public JSONObject getAllExpert(){
        return restService.getJson(RestURL.CONTROL + "cms/findAllExpert");
    }




    public List<JSONObject> groupByFruitTownName(JSONArray jsonArray, String type){
        List<JSONObject> list = jsonArray.stream()
                .map(x -> JSONObject.parseObject(JSONObject.toJSONString(x))).filter(x -> type.equals(x.getString("type")))
                .collect(Collectors.toList());
        Map<String, List<JSONObject>> mapList = list.stream().collect(Collectors.groupingBy(x -> x.getString("name")));
        List<JSONObject> jsonList = new ArrayList<>();
        for(String key : mapList.keySet()){
            List<JSONObject> jsonObjectList = mapList.get(key);
            Optional<JSONObject> json = jsonObjectList.stream().sorted(Comparator.comparing(x -> JSONObject.parseObject(x.toString()).getDate("createTime")).reversed()).findFirst();
            if(json.isPresent())
                jsonList.add(json.get());
        }
        return jsonList;
    }


    public JSONObject getAssembleResult(List<String> lineList, List<ImmutableBiMap> paramMap){
        JSONObject result = new JSONObject();
        List<JSONObject> list = new ArrayList<>();
        for(String data : lineList){
            String[] split = data.split(",");
            JSONObject object = new JSONObject();
            for(int i = 0; i < split.length; i++){
                String[] split1 = split[i].split("=");
                for(ImmutableBiMap map : paramMap){
                    String correspondingKey = String.valueOf(map.get("key"));
                    correspondingKey = correspondingKey.substring(0, correspondingKey.lastIndexOf("("));
                    String keyZ = String.valueOf(split1[0]);
                    if(correspondingKey.equals(keyZ)){
                        object.put(String.valueOf(map.get("value")), split1[1]);
                    }
                }
            }
            list.add(object);
        }
        result.put("title", paramMap);
        result.put("dataList", list);
        return result;
    }


    public JSONObject genPlantResult(){
        JSONObject object = new JSONObject();
        object.put("areaCnt", 0);                                                       // 总面积
        object.put("areaPlantCnt", 0);                                                  // 已种植面积
        object.put("areaNotPlantCnt", object.getDouble("areaCnt"));                // 未种植面积
        object.put("soilNum", 0);                                                       // 地块数量
        object.put("plantNum", 0);                                                       // 品种数量
        object.put("plantData", null);                                                  // 种植数据
        return object;
    }

    public List<JSONObject> genResult(Map<String, List<ShiJiRuiTong>> listMap){
        List<JSONObject> list = new ArrayList<>();
        for(String key : listMap.keySet()){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("paramName", key);
            jsonObject.put("dataList", listMap.get(key));
            list.add(jsonObject);
        }
        return list;
    }

    public List<JSONObject> genSDRKResult(Map<String, List<SDRKData>> listMap){
        List<JSONObject> list = new ArrayList<>();
        for(String key : listMap.keySet()){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("paramName", key);
            jsonObject.put("dataList", listMap.get(key));
            list.add(jsonObject);
        }
        return list;
    }

    public static List<ShiJiRuiTong> genXFXSjrtList(List<XinFengXiang> historyData) {
        List<ShiJiRuiTong> shiJiRuiTongList = new ArrayList<>();
        for (XinFengXiang xinFengXiang : historyData) {
            ShiJiRuiTong sjrt = new ShiJiRuiTong();
            sjrt.setCtime(DATE_TIME_FORMAT.format(xinFengXiang.getDateTime()));
            sjrt.setEquipmentId(xinFengXiang.getEquipmentId());
            sjrt.setParamVal(xinFengXiang.getEValue());
            sjrt.setParamName(xinFengXiang.getEName());
            sjrt.setParamUnit(xinFengXiang.getEUnit());
            shiJiRuiTongList.add(sjrt);
        }
        return shiJiRuiTongList;
    }
    public static List<ShiJiRuiTong> genOKQSjrtList(List<OKQENVData> historyData) {
        List<ShiJiRuiTong> shiJiRuiTongList = new ArrayList<>();
        for (OKQENVData okqenvData : historyData) {
            ShiJiRuiTong sjrt = new ShiJiRuiTong();
            sjrt.setCtime(okqenvData.getCTime());
            sjrt.setEquipmentId(okqenvData.getEquipmentId());
            sjrt.setParamVal(okqenvData.getParamVal());
            sjrt.setParamName(okqenvData.getParamName());
            sjrt.setParamUnit(okqenvData.getParamUnit());
            shiJiRuiTongList.add(sjrt);
        }
        return shiJiRuiTongList;
    }

    public static List<ShiJiRuiTong> genKBSjrtList(List<KeBaiData> historyData) {
        List<ShiJiRuiTong> shiJiRuiTongList = new ArrayList<>();
        for (KeBaiData keBaiData : historyData) {
            ShiJiRuiTong sjrt = new ShiJiRuiTong();
            sjrt.setCtime(keBaiData.getThattime().toString());
            sjrt.setEquipmentId(keBaiData.getEquipmentId());
            sjrt.setParamVal(keBaiData.getSenval());
            sjrt.setParamName(keBaiData.getSensorname());
            sjrt.setParamUnit(keBaiData.getUnit());
            shiJiRuiTongList.add(sjrt);
        }
        return shiJiRuiTongList;
    }


    public Object customParamSort(Object data, Equipment equipment) {
        List<ShiJiRuiTong> dataList = JSONObject.parseArray(JSONObject.toJSONString(data), ShiJiRuiTong.class);
        String manufacturer = equipment.getManufacturer();
        List<ImmutableBiMap> paramList = new ArrayList<>();
        if (EQU_TYPE_SOIL.equals(equipment.getType())) {
            paramList = EQU_MANUFACTURER_SJRT.equals(equipment.getManufacturer()) ? sjrtSoilParam : xFXSoilParam;
        } else if(EQU_TYPE_ENV.equals(equipment.getType())){
            paramList = EQU_MANUFACTURER_SJRT.equals(manufacturer) ? sjrtEnvParam : EQU_MANUFACTURER_XFX.equals(manufacturer) ? xfxEnvParam : EQU_MANUFACTURER_OKQ.equals(manufacturer) ? okqEnvParam : kbEnvParam;
        }
        if(CollectionUtils.isNotEmpty(paramList)){
            for (ShiJiRuiTong item : dataList) {
                for (Map map : paramList) {
                    if (String.valueOf(map.get("key")).contains(item.getParamName())) {
                        item.setSort(Integer.valueOf(map.get("sort").toString()));
                        break;
                    }
                }
            }
            return dataList.stream().sorted(Comparator.comparing(ShiJiRuiTong::getSort)).collect(Collectors.toList());
        }
        return dataList;
    }



    List<ImmutableBiMap> sjrtSoilParam = Arrays.asList(
            ImmutableBiMap.builder().put("key", "土壤温度10cm(℃)").put("value", "soilTemp10").put("sort", 1).build(),
            ImmutableBiMap.builder().put("key", "土壤温度30cm(℃)").put("value", "soilTemp30").put("sort", 2).build(),
            ImmutableBiMap.builder().put("key", "土壤温度50cm(℃)").put("value", "soilTemp50").put("sort", 3).build(),
            ImmutableBiMap.builder().put("key", "土壤湿度10cm(%)").put("value", "soilHumidity10").put("sort", 4).build(),
            ImmutableBiMap.builder().put("key", "土壤湿度30cm(%)").put("value", "soilHumidity30").put("sort", 5).build(),
            ImmutableBiMap.builder().put("key", "土壤湿度50cm(%)").put("value", "soilHumidity50").put("sort", 6).build(),
            ImmutableBiMap.builder().put("key", "土壤盐分(mg/l)").put("value", "soilSalinity").put("sort", 7).build(),
            ImmutableBiMap.builder().put("key", "土壤PH(ph)").put("value", "soilPH").put("sort", 8).build(),
            ImmutableBiMap.builder().put("key", "土壤磷(mg/L)").put("value", "soilPhosphorus").put("sort", 9).build(),
            ImmutableBiMap.builder().put("key", "土壤氮(mg/L)").put("value", "soilNitrogen").put("sort", 10).build(),
            ImmutableBiMap.builder().put("key", "土壤钾(mg/L)").put("value", "soilPotassium").put("sort", 11).build()
    );

    List<ImmutableBiMap> xFXSoilParam = Arrays.asList(
            ImmutableBiMap.builder().put("key", "土壤温度10cm(℃)").put("value", "soilTemp10").put("sort", 1).build(),
            ImmutableBiMap.builder().put("key", "土壤温度30cm(℃)").put("value", "soilTemp30").put("sort", 2).build(),
            ImmutableBiMap.builder().put("key", "土壤温度50cm(℃)").put("value", "soilTemp50").put("sort", 3).build(),
            ImmutableBiMap.builder().put("key", "土壤湿度10cm(%)").put("value", "soilHumidity10").put("sort", 4).build(),
            ImmutableBiMap.builder().put("key", "土壤湿度30cm(%)").put("value", "soilHumidity30").put("sort", 5).build(),
            ImmutableBiMap.builder().put("key", "土壤湿度50cm(%)").put("value", "soilHumidity50").put("sort", 6).build(),
            ImmutableBiMap.builder().put("key", "盐分(mg/l)").put("value", "soilSalinity").put("sort", 7).build(),
            ImmutableBiMap.builder().put("key", "磷(mg/L)").put("value", "soilPhosphorus").put("sort", 9).build(),
            ImmutableBiMap.builder().put("key", "氮(mg/L)").put("value", "soilNitrogen").put("sort", 10).build(),
            ImmutableBiMap.builder().put("key", "钾(mg/L)").put("value", "soilPotassium").put("sort", 11).build()
    );

    List<ImmutableBiMap> sjrtEnvParam = Arrays.asList(
            ImmutableBiMap.builder().put("key", "空气温度(℃)").put("value", "envTemp").put("sort", 1).build(),
            ImmutableBiMap.builder().put("key", "空气湿度(%)").put("value", "envHumidity").put("sort", 2).build(),
            ImmutableBiMap.builder().put("key", "光照强度(lux)").put("value", "lightIntensity").put("sort", 3).build(),
            ImmutableBiMap.builder().put("key", "大气压(kpa)").put("value", "atmos").put("sort", 4).build(),
            ImmutableBiMap.builder().put("key", "降雨量(mm/min)").put("value", "rainfall").put("sort", 5).build(),
            ImmutableBiMap.builder().put("key", "风速(m/s)").put("value", "windSpeed").put("sort", 6).build(),
            ImmutableBiMap.builder().put("key", "风向(°)").put("value", "windDirection").put("sort", 7).build(),
            ImmutableBiMap.builder().put("key", "总辐射(W/m2)").put("value", "totalRadiation").put("sort", 8).build()
    );

    List<ImmutableBiMap> xfxEnvParam = Arrays.asList(
            ImmutableBiMap.builder().put("key", "大气温度(℃)").put("value", "envTemp").put("sort", 1).build(),
            ImmutableBiMap.builder().put("key", "大气湿度(%RH)").put("value", "envHumidity").put("sort", 2).build(),
            ImmutableBiMap.builder().put("key", "太阳总辐射(W/m2)").put("value", "totalRadiation").put("sort", 3).build(),
            ImmutableBiMap.builder().put("key", "数字气压(hPa)").put("value", "atmos").put("sort", 4).build(),
            ImmutableBiMap.builder().put("key", "雨量(mm)").put("value", "rainfall").put("sort", 5).build(),
            ImmutableBiMap.builder().put("key", "风速(m/s)").put("value", "windSpeed").put("sort", 6).build(),
            ImmutableBiMap.builder().put("key", "风向(°)").put("value", "windDirection").put("sort", 7).build(),
            ImmutableBiMap.builder().put("key", "辐射累计(MJ/m2)").put("value", "radiationTotal").put("sort", 8).build(),
            ImmutableBiMap.builder().put("key", "雨量累计(mm)").put("value", "rainfallTotal").put("sort", 9).build(),
            ImmutableBiMap.builder().put("key", "叶面湿度(%RH)").put("value", "leafHumidity").put("sort", 10).build(),
            ImmutableBiMap.builder().put("key", "叶面温度(℃)").put("value", "leafTemp").put("sort", 11).build(),
            ImmutableBiMap.builder().put("key", "二氧化碳(PPM)").put("value", "carbon").put("sort", 12).build(),
            ImmutableBiMap.builder().put("key", "土壤温度(℃)").put("value", "soilTemp").put("sort", 13).build(),
            ImmutableBiMap.builder().put("key", "土壤湿度(%)").put("value", "soilHumidity").put("sort", 14).build(),
            ImmutableBiMap.builder().put("key", "电导率(mS/cm)").put("value", "conductivity").put("sort", 15).build(),
            ImmutableBiMap.builder().put("key", "光合有效辐射(W/m2)").put("value", "beaming").put("sort", 16).build(),
            ImmutableBiMap.builder().put("key", "pH值(ph)").put("value", "ph").put("sort", 17).build()
    );

    List<ImmutableBiMap> okqEnvParam = Arrays.asList(
            ImmutableBiMap.builder().put("key", "大气温度(℃)").put("value", "envTemp").put("sort", 1).build(),
            ImmutableBiMap.builder().put("key", "大气湿度(%RH)").put("value", "envHumidity").put("sort", 2).build(),
            ImmutableBiMap.builder().put("key", "大气压(hPa)").put("value", "envHumidity").put("sort", 3).build(),
            ImmutableBiMap.builder().put("key", "光照强度(W/m2)").put("value", "totalRadiation").put("sort", 4).build(),
            ImmutableBiMap.builder().put("key", "风向值").put("value", "atmos").put("sort", 5).build(),
            ImmutableBiMap.builder().put("key", "风向(°)").put("value", "rainfall").put("sort", 6).build(),
            ImmutableBiMap.builder().put("key", "风速(m/s)").put("value", "windSpeed").put("sort", 7).build(),
            ImmutableBiMap.builder().put("key", "降雨量(mm)").put("value", "windDirection").put("sort", 8).build(),
            ImmutableBiMap.builder().put("key", "土壤氧气(%)").put("value", "rainfallTotal").put("sort", 9).build(),
            ImmutableBiMap.builder().put("key", "土壤温度10cm(℃)").put("value", "radiationTotal").put("sort", 10).build(),
            ImmutableBiMap.builder().put("key", "土壤水分10cm(%)").put("value", "rainfallTotal").put("sort", 11).build(),
            ImmutableBiMap.builder().put("key", "土壤湿度10cm(%)").put("value", "rainfallTotal").put("sort", 11).build(),
            ImmutableBiMap.builder().put("key", "土壤温度20cm(℃)").put("value", "rainfallTotal").put("sort", 12).build(),
            ImmutableBiMap.builder().put("key", "土壤水分20cm(%)").put("value", "rainfallTotal").put("sort", 13).build(),
            ImmutableBiMap.builder().put("key", "土壤湿度20cm(%)").put("value", "rainfallTotal").put("sort", 13).build(),
            ImmutableBiMap.builder().put("key", "土壤温度30cm(℃)").put("value", "rainfallTotal").put("sort", 14).build(),
            ImmutableBiMap.builder().put("key", "土壤水分30cm(%)").put("value", "rainfallTotal").put("sort", 15).build(),
            ImmutableBiMap.builder().put("key", "土壤湿度30cm(%)").put("value", "rainfallTotal").put("sort", 15).build(),
            ImmutableBiMap.builder().put("key", "土壤温度40cm(℃)").put("value", "rainfallTotal").put("sort", 16).build(),
            ImmutableBiMap.builder().put("key", "土壤水分40cm(%)").put("value", "rainfallTotal").put("sort", 17).build(),
            ImmutableBiMap.builder().put("key", "土壤湿度40cm(%)").put("value", "rainfallTotal").put("sort", 17).build(),
            ImmutableBiMap.builder().put("key", "土壤温度50cm(℃)").put("value", "rainfallTotal").put("sort", 18).build()
    );



    List<ImmutableBiMap> kbEnvParam = Arrays.asList(
            ImmutableBiMap.builder().put("key", "空气温度(℃)").put("value", "envTemp").build(),
            ImmutableBiMap.builder().put("key", "相对湿度(%)").put("value", "envHumidity").build(),
            ImmutableBiMap.builder().put("key", "太阳辐射(W/㎡)").put("value", "radiation").build(),
            ImmutableBiMap.builder().put("key", "降雨量(mm)").put("value", "rainfall").build(),
            ImmutableBiMap.builder().put("key", "风速(m/s)").put("value", "windSpeed").build(),
            ImmutableBiMap.builder().put("key", "风向(Deg)").put("value", "windDirection").build(),
            ImmutableBiMap.builder().put("key", "大气压力(KPa)").put("value", "atmos").build(),
            ImmutableBiMap.builder().put("key", "大气压(hPa)").put("value", "atmos2").build(),
            ImmutableBiMap.builder().put("key", "二氧化碳(PPM)").put("value", "carbon").build(),
            ImmutableBiMap.builder().put("key", "有效光合度 (μmol/(m²*s))").put("value", "ep").build(),
            ImmutableBiMap.builder().put("key", "土壤水分(%)").put("value", "soilMoisture").build(),
            ImmutableBiMap.builder().put("key", "土壤温度(℃)").put("value", "soilTemp").build(),
            ImmutableBiMap.builder().put("key", "土壤EC值(uS/cm)").put("value", "ec").build(),
            ImmutableBiMap.builder().put("key", "土壤PH值(ph)").put("value", "soilPh").build(),
            ImmutableBiMap.builder().put("key", "叶面温度(℃)").put("value", "leafTemp").build(),
            ImmutableBiMap.builder().put("key", "叶面湿度(%RH)").put("value", "leafHumidity").build(),
            ImmutableBiMap.builder().put("key", "电池(mV)").put("value", "battery").build(),
            ImmutableBiMap.builder().put("key", "太阳能电池板(mV)").put("value", "solarPanel").build(),
            ImmutableBiMap.builder().put("key", "PCB板温度(℃)").put("value", "pcb").build(),
            ImmutableBiMap.builder().put("key", "太阳全辐射(W/㎡)").put("value", "sunRadiation").build(),
            ImmutableBiMap.builder().put("key", "WSN Emtpy(mV)").put("value", "wsn").build(),
            ImmutableBiMap.builder().put("key", "sdi12电压(mV)").put("value", "sdi12").build(),
            ImmutableBiMap.builder().put("key", "无线传感器网络电量(mV)").put("value", "ele").build(),
            ImmutableBiMap.builder().put("key", "植物有效辐射(umol/(㎡·s))").put("value", "plantER").build(),
            ImmutableBiMap.builder().put("key", "信号(ind)").put("value", "signal").build(),
            ImmutableBiMap.builder().put("key", "紫外线指数(UVI)").put("value", "uv").build(),
            ImmutableBiMap.builder().put("key", "土壤水分5te(%)").put("value", "soil5te").build(),
            ImmutableBiMap.builder().put("key", "土壤温度5te(℃)").put("value", "soilTemp5te").build(),
//            ImmutableBiMap.builder().put("key", "CO2(ppm)").put("value", "carbon").build(),
            ImmutableBiMap.builder().put("key", "土壤水分EC5(%)").put("value", "ec5").build()
    );


    public static void main(String[] args) {

        System.out.println(LocalDateTime.of(LocalDate.now(), LocalTime.of(1, 1, 1)));

        System.out.println("15".split(".")[0]);



        ObjectMapper objectMapper = new ObjectMapper();

        try {
            // 从文件中读取 JSON 数据
            File file = new File("E:\\紫音村.json");

            JSONObject jsonObject = objectMapper.readValue(file, JSONObject.class);

            // 使用解析得到的对象
            List<SoilDTO> soilDTOList = JSONObject.parseArray(
                    JSONObject.parseObject(
                            JSONObject.toJSONString(jsonObject.getJSONArray("ObjItems").get(0))
                    )
                            .getJSONObject("Object")
                            .getJSONObject("ObjectDetail")
                            .getString("ObjChildren"), SoilDTO.class
            );
            List<BaseSoil> baseSoilList = new ArrayList<>();
            for(SoilDTO soilDTO : soilDTOList){
                BaseSoil baseSoil = new BaseSoil();
                SoilObjectDTO object = soilDTO.getObject();
                SoilObjectDetailDTO objectDetail = object.getObjectDetail();

                List<Double> latlng = objectDetail.getLatlng();
                int latLngsize = latlng.size();
                if (latLngsize % 2 != 0) {
                    System.out.println("坐标点集合size为奇数，" + object.getName());
                }
                int half = latLngsize / 2;


                List<Double> latList = latlng.subList(0, half);
                List<Double> lngList = latlng.subList(half, latlng.size());

                List<JSONObject> coordinateList = new ArrayList<>();
                for(Double lat : latList){
                    JSONObject coordinate = new JSONObject();
                    coordinate.put("lat", lat);
                    coordinateList.add(coordinate);
                }
                int coordinateSize = coordinateList.size();
                for(int i = 0; i < coordinateSize; i++){
                    JSONObject coordinate = coordinateList.get(i);
                    coordinate.put("lng", lngList.get(i));
                }
                baseSoil.setCoordinate(JSONObject.toJSONString(coordinateList));
                baseSoil.setName(object.getName());
                baseSoilList.add(baseSoil);
            }
//            baseSoilList.forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

}
